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

时间:2014-04-02 12:08:46

标签: java jar classloader

我正在尝试从jar文件中的文件中读取类名,该文件传递给方法并将确定的类名放入传递的StringBuilder中。

对于驱动程序文件jtds-1.3.1.jar我应该获得net.sourceforge.jtds.jdbc.Driver但我得到sun.jdbc.odbc.JdbcOdbcDriver而不是传递文件。我想这个子类加载器是从/META-INF/services/java.sql.Driver读取的,它位于我的类路径的某个地方(但我真的不知道在哪里),我无法弄清楚如何管理这个类加载器的事情。

以下有关此事的代码:

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

根据javadoc of getResource method:"此方法将首先在父类加载器中搜索资源;"似乎getResourceAsAstream具有相同的行为。

播种如何强制从子类加载器加载?

1 个答案:

答案 0 :(得分:1)

你可以在同一个java程序中拥有多个jdbc驱动程序,这没什么不对。您是否尝试ClassLoader.getResourceUrls()(将返回所有匹配的网址)?然后你就可以找到你想要的那个。

或者,那些META-INF文件实际上是ServiceLoader机制的一部分,所以也许你最好还是使用那个类。

最后,如果您只是尝试使用jdbc驱动程序,则不需要执行任何操作。你只需要用正确的url创建一个驱动程序,如果它已经在类路径上,jdbc框架将自动找到正确的驱动程序。

更新:

如果您的目的是检查特定的 jar文件,那么您就不应该使用ClassLoader,因为它会执行您不想要的各种事情。只需使用JarFile检查jar并提取所需的信息。