jenkins发布应用时,对linux动态库的加载,有别于直接使用ssh连接到服务端的发布方式。原因还不是很明确,jenkins也是通过SSH的方式,使用与直接使用ssh登录服务发布应用时,使用同样的用户名,因此不可能是权限上的问题。我的猜想可能jenkins通过SSH链接的方式,可能直接跳过了某些bash相关初始化,因为从事后反证加载默认的动态库没有问题,只是在加载附加目录下的动态库时才出现无法正确加载动态库,有待进一步验证,但直接使用ssh连接并发布应用,可以正常加载附加目录下的动态库。
解决办法:把放在特殊位置的动态库拷贝到上述默认目录比如/lib(64)/下即可。
问题延伸:其实问题的解决是很容易的,但发现问题的过程有必要重提一下,因为本人的应用是一个java application(不需要中间件服务器如tomcat),使用jenkins发布并运行application,与直接发布效果一样,没有任何异常信息。但其中有一个功能点在jenkins下失效了,此功能点是java调用外部程序OpenOffice Server。
未发现问题时的源码片段:
pro = Runtime.getRuntime().exec(command.toString());
buffer = new BufferedReader(new InputStreamReader(pro.getInputStream()));
while(buffer.readLine()!=null);
int rtstate = pro.waitFor();
return rtstate;
发现返回的rtstate是127,一头雾水了,一开始以为只要rtstate>=0都是正确的状态,但正确是只有rtstate为0是,才算正常调用并执行了外部程序。那127只是个错误代号,如何查看其详细报错信息呢?看以下源码片段:
pro = Runtime.getRuntime().exec(command.toString());
buffer = new BufferedReader(new InputStreamReader(pro.getInputStream()));
while(buffer.readLine()!=null);
int rtstate = pro.waitFor();
if(rtstate!=0){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i=-1;
while((i=pro.getErrorStream().read())!=-1){
baos.write(i);
}
/** 粗糙的把出错打出来,有空进一步自定义Exception **/
System.out.println(baos.toString());
baos.close();
}
return rtstate;
加上这一段专门捕获错误信息后,很清楚的把错误输出到控制台:找不到xxx.so!,回到本文的开头,第一次看到这个错误信息真是意想不到,jenkins的发布还能引起这样的问题。