获取apusic下class文件路径的问题

情况描述:

将某一个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


原文链接: http://blog.csdn.net/cyq1984/article/details/5476825

你可能感兴趣的:(获取apusic下class文件路径的问题)