问题:
当把用Spring框架开发的java project(在Eclipse中可以正常执行)导出为可执行jar包时,单独执行jar包会出现无法找到applicationContext.xml文件的问题;
原因:
applicationContext.xml文件是被打包到jar包内部的,而jar包独立运行时,该程序只能识别jar外部的文件,无法识别内部文件。
解决方案:
在启动初始化期间,将jar包内部的文件拷贝到jar包外部相对路径中。
代码如下:
//jarFullFileName: the file name with full path in jar.
//newFilePath: the new file directory. "./" means the current directory of jar file.
public boolean newFileFromJar(String jarFullFileName, String newFilePath){
String[] jarFilePath = null;
String newFileName = null;
File file = null;
OutputStream os = null;
InputStream is = null;
try {
//check if the source file existed.
is = Configer.class.getResourceAsStream(jarFullFileName);
if(is == null){
System.out.println("Fail to get input stream.");
return false;
}
//get the new file's full path name
jarFilePath = jarFullFileName.split("/");
newFileName = newFilePath+jarFilePath[jarFilePath.length-1];
System.out.println(newFileName);
//open or create the new file
file = new File(newFileName);
if(file.exists()){
System.out.println("file existed.");
}
else {
if(file.createNewFile() == false) {
System.out.println("fail to create new file "+newFileName);
return false;
}
}
os = new FileOutputStream(file);
//copy file content
byte[] buff = new byte[1024];
while (true) {
int readed = is.read(buff);
if (readed == -1) {
break;
}
byte[] temp = new byte[readed];
System.arraycopy(buff, 0, temp, 0, readed);
os.write(temp);
}
}
catch(Exception e) {
e.printStackTrace();
return false;
}
//close the io streams
try {
if(os != null)
os.close();
if(os != null)
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return true;
}
...
//注意:参数jarFullFileName是jar包内部的相对路径,如路径"/applicationContext.xml"表示jar包根目录下的文件
newFileFromJar("applicationContext.xml",".");//copy the file to the current directory of jar file
注意:
在使用独立jar文件运行的java代码中,没法使用ClassPathXmlApplicationContext(..)来加载Spring的配置文件,因为该方法只能用于读取WEB-INF\classes下的配置文件。此时需要使用FileSystemXmlApplicationContext(..)方法来加载配置文件。