问题:
当把用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(..)方法来加载配置文件。