情况描述:
将某一个java类和其他一些类打成jar包放到了Apusic-6.0/lib下,然后分别用两种模式启动apusic:一种是直接启动apusic服务器,一种是将apusic配置到eclipse中启动。
对于这两种启动模式在此类中直接用getResource("/");时得到的是不同的路径;
第一种启动得到的结果是file:/APUSIC_DOMAIN/domains/mydomain/./
第二种启动得到的是file:/APUSIC_DOMAIN/classes/
这个问题也许是apusic类加载机制的某些问题,也许另有其他原因,不知道在其他的应用服务器下是否会出现同样的问题。
由于需求是获取绝对路径,并且是在所有的应用之前获取,因此没办法使用Servlet的getRealPath(String str)方法,更不用考虑Session与Application的相关方法了。提炼一下需求,就是无论当前工程当前路径是什么,都要获取到同样的一个绝对路径。而且又要避开上述问题。
搜索下,发现有位仁兄早就解决了这个问题,通过一个封装好的Path类,直接获取某个class文件的绝对路径,并且经过测试,无论何种情况下,都是绝对正宗的绝对路径,此Path类的代码如下所示:
import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.security.CodeSource; import java.security.ProtectionDomain; /** * @author * * 这个类提供了一些根据类的class文件位置来定位的方法。 */ public class Path { /** * 获取一个类的class文件所在的绝对路径。 这个类可以是JDK自身的类,也可以是用户自定义的类,或者是第三方开发包里的类。 * 只要是在本程序中可以被加载的类,都可以定位到它的class文件的绝对路径。 * * @param cls * 一个对象的Class属性 * @return 这个类的class文件位置的绝对路径。 如果没有这个类的定义,则返回null。 */ public static String getPathFromClass(Class cls) throws IOException { String path = null; if (cls == null) { throw new NullPointerException(); } URL url = getClassLocationURL(cls); if (url != null) { path = url.getPath(); if ("jar".equalsIgnoreCase(url.getProtocol())) { try { path = new URL(path).getPath(); } catch (MalformedURLException e) { } int location = path.indexOf("!/"); if (location != -1) { path = path.substring(0, location); } } File file = new File(path); path = file.getCanonicalPath(); } return path; } /** * 这个方法可以通过与某个类的class文件的相对路径来获取文件或目录的绝对路径。 通常在程序中很难定位某个相对路径,特别是在B/S应用中。 * 通过这个方法,我们可以根据我们程序自身的类文件的位置来定位某个相对路径。 * 比如:某个txt文件相对于程序的Test类文件的路径是../../resource/test.txt, * 那么使用本方法Path.getFullPathRelateClass("../../resource/test.txt",Test.class) * 得到的结果是txt文件的在系统中的绝对路径。 * * @param relatedPath * 相对路径 * @param cls * 用来定位的类 * @return 相对路径所对应的绝对路径 * @throws IOException * 因为本方法将查询文件系统,所以可能抛出IO异常 */ public static String getFullPathRelateClass(String relatedPath, Class cls) throws IOException { String path = null; if (relatedPath == null) { throw new NullPointerException(); } String clsPath = getPathFromClass(cls); File clsFile = new File(clsPath); String tempPath = clsFile.getParent() + File.separator + relatedPath; File file = new File(tempPath); path = file.getCanonicalPath(); return path; } /** * 获取类的class文件位置的URL。这个方法是本类最基础的方法,供其它方法调用。 */ private static URL getClassLocationURL(final Class cls) { if (cls == null) throw new IllegalArgumentException("null input: cls"); URL result = null; final String clsAsResource = cls.getName().replace('.', '/').concat( ".class"); final ProtectionDomain pd = cls.getProtectionDomain(); // java.lang.Class contract does not specify // if 'pd' can ever be null; // it is not the case for Sun's implementations, // but guard against null // just in case: if (pd != null) { final CodeSource cs = pd.getCodeSource(); // 'cs' can be null depending on // the classloader behavior: if (cs != null) result = cs.getLocation(); if (result != null) { // Convert a code source location into // a full class file location // for some common cases: if ("file".equals(result.getProtocol())) { try { if (result.toExternalForm().endsWith(".jar") || result.toExternalForm().endsWith(".zip")) result = new URL("jar:".concat( result.toExternalForm()).concat("!/") .concat(clsAsResource)); else if (new File(result.getFile()).isDirectory()) result = new URL(result, clsAsResource); } catch (MalformedURLException ignore) { } } } } if (result == null) { // Try to find 'cls' definition as a resource; // this is not // document.d to be legal, but Sun's // implementations seem to //allow this: final ClassLoader clsLoader = cls.getClassLoader(); result = clsLoader != null ? clsLoader.getResource(clsAsResource) : ClassLoader.getSystemResource(clsAsResource); } return result; } public static void main(String[] args) { try { System.out.println(getPathFromClass(Path.class)); System.out.println(getFullPathRelateClass("../test/abc/..", Path.class)); } catch (Exception e) { e.printStackTrace(); } } }
在调用配置文件时,不再使用“getResource("/");”方法,而是直接调用此Path类的“getPathFromClass”方法,完成绝对路径的获取,最终,无论何种情况下,系统获取的都是实际的类文件的实际绝对路径,此问题解决。
本文参考Path类实现,出处:http://long5534.javaeye.com/blog/107497