문제

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.

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. 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.

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;" It seems that getResourceAsAstream has the same behaviour.

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. Did you try ClassLoader.getResourceUrls() (which will return all matching urls) instead? 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.

Lastly, if you are just trying to use a jdbc driver, you don't need to do any of this. 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.

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. Just use JarFile to examine the jar and extract the information you desire.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top