-1

I have a jar, which contains all needed external libs. All i want: load libraries in runtime so i can use them as i could if they were in classpath.

Some visualization:

-main.jar
-lib.jar
--apache.jar
--someother.jar
---aclass.class
etc.

Some not really helpful code:

    // loading libraries
    ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
    ArrayList<URL> librariesJarsURL = new ArrayList<>();
    JarFile libJar = new JarFile(libBundle);
    Enumeration libJarEnum = libJar.entries();
    while (libJarEnum.hasMoreElements()) {
        JarEntry libJarEntry = (JarEntry) libJarEnum.nextElement();
        if (!libJarEntry.isDirectory() && libJarEntry.getName().endsWith(".jar")) {
            librariesJarsURL.add(new URL("jar:file://" + (libBundle.getAbsolutePath().replace("\\", "/")) + "!/" + libJarEntry.getName()));
        }
    }
    if (librariesJarsURL.size() > 0) {
        for (URL libraryJarURL : librariesJarsURL) {
            System.out.println(libraryJarURL);
        }
        ClassLoader urlCL = URLClassLoader.newInstance(librariesJarsURL.toArray(new URL[0]), contextCL);
        Thread.currentThread().setContextClassLoader(urlCL);
    }
    System.out.println(StringUtils.difference("zero", "zero141"));

The last is from Commons Apache String utils that also should be included but aint giving me NoClassDefFoundError and ClassNotFoundException.

Also, i tried to use "reflection hack" but it aint working as well.

Thats the problem, guys... Any ideas?

EDIT: libBundle is kinda File object...

UPD:

/*
 * Reflection hack :/
 */
public static void addURL(URL url) throws Exception
{
    URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    Class uclclass = URLClassLoader.class;

    // Use reflection
    Method method = uclclass.getDeclaredMethod("addURL", new Class[]{URL.class});
    method.setAccessible(true);
    method.invoke(classLoader, new Object[]{url});
}

Used libBundle.toURI().toURL() - same errors,
addURL(new URL("jar:file://" + (libBundle.getAbsolutePath().replace("\\", "/")) + "!/")); - thats same,
tried to do same with all jars in lib.jar - same.
Tried URLClassLoader libraryLoader = new URLClassLoader(librariesJarsURL.toArray(new URL[0]), GlobalInit.class.getClassLoader()); - same.

RussianVodka
  • 450
  • 1
  • 6
  • 18
  • @nos reflection hack - using reflection for URLClassLoader addURL function to inject our URL into system classpath stuff... Laying out de code... – RussianVodka Nov 20 '14 at 14:48
  • Ok, @nos. Then what actual "points" i need to include to make my classloader works? I mean where i need to add it or smth... – RussianVodka Nov 20 '14 at 14:55

1 Answers1

-1

So. Found that Reference jars inside a jar. That means i cant just make own classloader for this situation. Its kinda sad, cause i tried... Ok. I think answer would be: rework ur library building stuff to avoid this. Thanks, guys.

Community
  • 1
  • 1
RussianVodka
  • 450
  • 1
  • 6
  • 18