为什么toUri()。toURL()在开始时加载本地路径?

时间:2015-05-04 13:17:32

标签: java classloader

我有部分代码从文件加载类,然后创建它们的实例。现在我已经用我的本地项目对它们进行了单元测试,一切似乎都正常。

毕竟,我想把我的部分与骆驼联系起来,从这一点开始,负责加载其他类的类开始表现得很奇怪。似乎toUri()。toURL()在作为参数给出的实际路径之前添加本地路径。所以在这种情况下,我得到以下值。

DIR =       file:D:\WORKSPACES\PROJ1\Parser\target\classes\com\somecompany\someproduct\SpecializedParser\EventReasonSpecializedParserImpl.class
PATH =      file:D:/WORKSPACES/PROJ1/Parser/target/classes/com/somecompany/someproduct/SpecializedParser/
LOADPATH =  file:/D:/WORKSPACES/PROJ1/TestPrograms/ContentBasedRouterTestServer/file:D:/WORKSPACES/PROJ1/Parser/target/classes/com/somecompany/someproduct/SpecializedParser/EventReasonSpecializedParserImpl.class
PACKCLASSNAME = com.somecompany.someproduct.SpecializedParser.EventReasonSpecializedParserImpl

应该是

PATH =      file:D:/WORKSPACES/PROJ1/Parser/target/classes/com/somecompany/someproduct/SpecializedParser/
LOADPATH =  file:D:/WORKSPACES/PROJ1/Parser/target/classes/com/somecompany/someproduct/SpecializedParser/EventReasonSpecializedParserImpl.class
PACKCLASSNAME = com.somecompany.someproduct.SpecializedParser.EventReasonSpecializedParserImpl

检查加载路径的差异。背后的代码是:

public class ClassLoaderHelper {
  static HashMap<String, Class> classKeeper = new HashMap<>();
  public static Class getClasFromPath(String path, String className, String packageName) throws ParserException {
   String packPlusClassName = packageName + className;

   if (classKeeper.containsKey(packPlusClassName)) {
     return classKeeper.get(packPlusClassName);
   }

   File dir = new File(path + className + ".class");
   URL loadPath = null;
   try {
     loadPath = dir.toURI().toURL();
   } catch (MalformedURLException mue) {
     throw new ParserException("Malformed URL Exception - " + mue.getMessage());
   }
   URL[] classUrl = new URL[]{loadPath};
   ClassLoader cl = new URLClassLoader(classUrl);
   System.out.println("DIR = " + dir);
   System.out.println("PATH = " + path);
   System.out.println("LOADPATH = " + loadPath);
   System.out.println("PACKCLASSNAME = " + packPlusClassName);

   Class returnClass = null;
   try {
     returnClass = cl.loadClass(packPlusClassName);
   } catch (ClassNotFoundException cnfe) {
     throw new ParserException("Parser class not found: " + className + " in package " + packageName);
   }
   classKeeper.put(packPlusClassName, returnClass);
   return returnClass;
 }

}

为什么,当它从camel调用时,它会将本地路径放在loadpath的开头?如何避免这种情况 - 我甚至不知道从哪里开始,因为toURI()。toURL()应该只返回我感兴趣的东西 - 仅此而已。

1 个答案:

答案 0 :(得分:0)

最后我无法使用URLClassLoader所以我尝试了另一种方法,因此我得到了:

public class ClassLoaderHelper extends ClassLoader {

  public ClassLoaderHelper(ClassLoader parent) {
    super(parent);
  }

static HashMap<String, Class> classKeeper = new HashMap<>();

public Class getClasFromPath(String path, String className, String packageName) throws MalformedURLException, URISyntaxException, IOException {
  String packPlusClassName = packageName + className;

  if (classKeeper.containsKey(packPlusClassName)) {
    return classKeeper.get(packPlusClassName);
  }

  URL newUrl = new URL("file:" + path + className + ".class").toURI().toURL();

  URLConnection connection = newUrl.openConnection();
  ByteArrayOutputStream buffer;
  try (InputStream input = connection.getInputStream()) {
    buffer = new ByteArrayOutputStream();
    int data = input.read();
    while (data != -1) {
      buffer.write(data);
      data = input.read();
    }
  }

  byte[] classData = buffer.toByteArray();
  Class returnClass = defineClass(null, classData, 0, classData.length);
  classKeeper.put(packPlusClassName, returnClass);
  return returnClass;
  }
}

路径的形状如下:

String path = "D:\\WORKSPACES\\product\\component\\target\\classes\\com\\company\\product\\ContextSpecializedParser\\";

另外我无法实例加载类,所以我使用调用方法mechasnim如下:

ClassLoaderHelper clh = new ClassLoaderHelper(componentClass.class.getClassLoader());

specParser = clh.getClasFromPath(path, parser.ClassName, packageName).newInstance();
    Class[] cArg = new Class[2];
    cArg[0] = Object.class;
    cArg[1] = String.class;

    method = specParser.getClass().getMethod("Method", cArg);