简体   繁体   English

JAR不在类路径上,强制类加载器从其读取文件

[英]JAR not on classpath, force classloader to read file from it

I am trying to read class name from a file inside a jar file which is passed to the method and put the determined class name into passed StringBuilder. 我试图从传递给方法的jar文件中的文件读取类名,并将确定的类名放入传递的StringBuilder中。

For the driver file jtds-1.3.1.jar i should get net.sourceforge.jtds.jdbc.Driver but I get sun.jdbc.odbc.JdbcOdbcDriver instead of it independently from passed file. 对于驱动程序文件jtds-1.3.1.jar我应该获取net.sourceforge.jtds.jdbc.Driver但是我要获取sun.jdbc.odbc.JdbcOdbcDriver而不是独立于传递的文件。 I suppose the child classloader reads from /META-INF/services/java.sql.Driver which is somewhere on my classpath (but I don't really know where) and I can't figure it out how to manage this classloader thing. 我想子类加载器从/META-INF/services/java.sql.Driver中读取,该文件位于我的类路径上的某个位置(但我真的不知道在哪里),而且我不知道该如何管理该类加载器。

The code concerning this matter below: 有关此问题的代码如下:

public String determineAndSetDriverClass(File jar, StringBuilder classNameBuilder)
{
    BufferedReader br = null;
    URLClassLoader child = null;
    try
    {
        URL[] urls = {jar.toURI().toURL()};
        child = new URLClassLoader(urls, this.getClass().getClassLoader());
        br = new BufferedReader(new InputStreamReader(child.getResourceAsStream("/META-INF/services/java.sql.Driver")));
        classNameBuilder.append(br.readLine());
        return null;
    }
    catch (Exception e)
    {
        e.printStackTrace();
        return e.getMessage();
    }
    finally
    {
        try
        {
            if (br != null)
                br.close();
            if (child != null)
                child.close();
        }
        catch (IOException ioe)
        {
            ioe.printStackTrace();
        }
    }
}

According to javadoc of getResource method : "This method will first search the parent class loader for the resource;" 根据getResource方法的javadoc :“此方法将首先在父类加载器中搜索资源;” It seems that getResourceAsAstream has the same behaviour. 似乎getResourceAsAstream具有相同的行为。

Sow how can I force loading from child classloader? 播种如何强制从子类加载器加载?

You can have multiple jdbc drivers in the same java program, there's nothing wrong with that. 在同一个Java程序中可以有多个jdbc驱动程序,这没有什么不对。 Did you try ClassLoader.getResourceUrls() (which will return all matching urls) instead? 您是否尝试过ClassLoader.getResourceUrls() (它将返回所有匹配的URL)? then you can find the one you want. 然后您可以找到想要的那个。

Alternately, those META-INF files are really part of the ServiceLoader mechanism, so maybe you would be better off using that class. 另外,那些META-INF文件实际上是ServiceLoader机制的一部分,因此使用该类可能会更好。

Lastly, if you are just trying to use a jdbc driver, you don't need to do any of this. 最后,如果您只是尝试使用jdbc驱动程序,则无需执行任何操作。 you just need to create a driver with the correct url, and the jdbc framework will automatically find the right driver if it is already on the classpath. 您只需要创建一个具有正确URL的驱动程序,并且jdbc框架会自动找到正确的驱动程序(如果它已在类路径中)。

UPDATE: 更新:

If your intent is to examine a specific jar file, then you shouldn't be using a ClassLoader, as it will do all kinds of things you don't want. 如果您打算检查特定的 jar文件,那么您不应该使用ClassLoader,因为它会执行所有您不需要的事情。 Just use JarFile to examine the jar and extract the information you desire. 只需使用JarFile检查jar并提取所需的信息即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM