2014-02-20 3 views
1

Привет Я создаю плагин, который требует динамической загрузки кувшинов и доступа к классам и методам этих банок. Я попытался с помощью URLClassLoader и я в состоянии загружать классы, как показано нижеКак загружать все банки из каталога динамически?

URL myJarFile = new URL("jar","","file:"+jarPath); 
URLClassLoader sysLoader =(URLClassLoader)ClassLoader.getSystemClassLoader(); 
Class sysClass = URLClassLoader.class; 
Method sysMethod = sysClass.getDeclaredMethod("addURL", new Class[]{URL.class}); 
sysMethod.setAccessible(true); 
sysMethod.invoke(sysLoader, new Object[]{myJarFile}); 

Но проблема с этим состоит в том, что мы должны загрузить классы в ClassLoader, указав свое имя индивидуально. Я хочу загрузить все классы из всех банок в пути класса и получить доступ к ним в любой момент времени.

Возможно ли это с помощью URLClassLoader? Если нет, то какие другие варианты? Насколько полезен OSGI для достижения этого?

Заранее благодарен!

+0

«Я хочу загрузить все классы из всех банок в пути класса и получить к ним доступ в любой момент времени». Зачем??? Ваш вопрос не подлежит обсуждению без какого-либо представления о вашей мотивации. Если вы пытаетесь создать расширяемое приложение с возможностью добавления плагинов, вы должны * абсолютно * использовать OSGi. –

ответ

1

Сначала необходимо загрузить свою банку, а затем загрузить требуемый класс.

URL myJarFile = new URL("jar","","file:"+jarPath); 
URLClassLoader child = new URLClassLoader (myJarFile , this.getClass().getClassLoader()); 
Class classToLoad = Class.forName ("com.MyClass", true, child); 
Method method = classToLoad.getDeclaredMethod ("myMethod"); 
Object instance = classToLoad.newInstance(); 
Object result = method.invoke (instance); 

Тогда вы можете получить список всех классов в файле фляги первый:

List<String> classNames=new ArrayList<String>(); 
ZipInputStream zip=new ZipInputStream(new FileInputStream("/path/to/jar/file.jar")); 
for(ZipEntry entry=zip.getNextEntry();entry!=null;entry=zip.getNextEntry()) 
    if(entry.getName().endsWith(".class") && !entry.isDirectory()) { 
     StringBuilder className=new StringBuilder(); 
     for(String part : entry.getName().split("/")) { 
      if(className.length() != 0) 
       className.append("."); 
      className.append(part); 
      if(part.endsWith(".class")) 
       className.setLength(className.length()-".class".length()); 
     } 
     classNames.add(className.toString()); 
    } 

После того, как у вас есть список классов, выполните следующие действия:

File file = new File("Absolute Path to your jar"); 
      URL url = file.toURI().toURL(); 
      URL[] urls = {url}; 
      ClassLoader loader = new URLClassLoader(urls); 
      Class myClass = loader.loadClass(classNames.get(0)); 
      System.out.println("Executing..."); 
      Object tester = myClass.newInstance(); 
     System.out.println("Test"); 
+0

Tats catch .. Я не буду знать, какой класс загрузить .. thr - это много классов в этой jar, и я хочу, чтобы все классы были доступны в классе-пути ... – Yunkhan

+0

Спасибо @Mobility. Это действительно решит проблему загрузки всех классов. Но теперь, если я хочу получить доступ к определенному классу laoded jar, скажите 'SomeJarClass obj = SomeJarClass.getInstance()', это должно работать с тех пор, как все классы этого jar загружены_. Но он снова дает исключение класса, не найденное. – Yunkhan

+0

Я нашел решение для этого. На самом деле то, как я называл этот класс, было неправильным. Теперь я могу ладонировать банки. загрузите один основной класс, который внутренне использует экземпляры других классов из других банок, и все они доступны во время выполнения. – Yunkhan

1

Apache Felix File Install может быть именно тем, чего вы хотите. Он будет контролировать назначенный каталог и динамически загружать в него любые пакеты. Только пакеты, экспортируемые пакетами, будут доступны для других пакетов в пути к классам, но будут загружены все классы.

Смежные вопросы