2015-05-04 86 views
-1

我有部分代码从文件中加载类,然后创建它们的实例。现在我有单元测试他们与我的本地项目,一切似乎正常工作。为什么toUri()。toURL()会在开始时加载本地路径?

毕竟,我想把自己的一部分与骆驼联系起来,从这一点开始,负责加载其他类的类开始表现得很奇怪。看来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 

入住loadpath的差异。后面的代码是:

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; 
} 

}

为什么,当它从骆驼叫,它把对loadpath的beggining本地路径?如何避免这种情况 - 我甚至不知道从哪里开始,因为toURI()。toURL()应该只返回我感兴趣的内容 - 没有什么更多,没有什么比。

+0

1)为什么你给路径从“file:”开始到'Dir'构造函数?为什么不只是本地路径? 2)为什么你不在“file:”之后加上“/”? –

+0

我认为最简单的答案是单元测试通过。当一切都过去了,我不在乎:/ TDD的弱点。 –

+0

好的,我删除了文件:从dir初始化。加载路径似乎更好,但仍然缺少一些东西。问题在于 - 为什么它早些时候工作? –

回答

0

Finaly我无法使用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); 
相关问题