2016-04-17 3 views
0

У меня есть простая система плагинов, которая загружает внешние плагины JAR в основное приложение. Для этого я использую Mountainblade Modular. Не уверен, как они это делают «под капотом», но, вероятно, это что-то стандартное.Чтение изображений с внешнего JAR

Это прекрасно работает, я создаю классы из внешней банки, и все это работает. За исключением того, что некоторые плагины снабжены значками/изображениями. Я немного не уверен в том, как я могу загружать/ссылаться на изображения из этого внешнего JAR (с кодом внутри этого внешнего JAR, поскольку он запускается в контексте основного JAR, типа)

Как я должен подходить к этому?

+0

Где находятся файлы JAR, расположенные относительно вашего пути к классу? –

+0

Я не очень уверен в этом решении, хотя, если ABC является вашим классом, , то ABC.class.getClassLoader.getResource() может помочь вам –

+0

@TimBiegeleisen в основном при создании основного основного приложения jar, рядом с ним есть папка с плагинами , и что другие внешние банки находятся в папке плагинов. –

ответ

1

Эта проблема не так проста, как кажется.

Когда вы загружаете классы из внешней банки, они «загружаются» в JVM. Под «загрузкой» в JVM я подразумеваю, что JVM отвечает за их хранение в памяти. Обычно это делается так:

ClassLoader myClassLoader = new MyClassLoader(jarFileContent); 
Class myExtClass = myClassLoader.loadClass(myClassName); 

ресурсов из баночек пути к классам можно легко получить доступ с

InputStream resourceStream = myClass.getResourceAsStream("/myFile.txt"); 

Вы можете сделать это, потому что эти банки находятся в пути к классам, я имею в виду их местонахождение неизвестно. Эти файлы не сохраняются в памяти. Когда доступ к ресурсу, JVM может искать его в банках classpath (например, в файловой системе).

Но для внешних банок это совершенно другое: баночка происходит из ниоткуда, обрабатывается и забывается. JVM не загружает из нее ресурсы в памяти. Чтобы получить доступ к этим файлам, вам необходимо вручную организовать их хранение. Я сделал это один раз, чтобы поделиться кодом. Это поможет вам понять основную идею (но, вероятно, не поможет вам в вашей конкретной библиотеке).

// Method from custom UrlClassLoader class. 
// jarContent here is byte array of loaded jar file. 
// important notes: 
// resources can be accesed only with this custom class loader 
// resource content is provided with the help of custom URLStreamHandler 
@Override 
protected URL findResource(String name) {  
    JarInputStream jarInputStream; 
    try { 
     jarInputStream = new JarInputStream(new ByteArrayInputStream(jarContent)); 
     JarEntry jarEntry; 
     while (true) { 
      jarEntry = jarInputStream.getNextJarEntry(); 
      if (jarEntry == null) { 
       break; 
      } 
      if (name.equals(jarEntry.getName())) { 
       final byte[] bytes = IOUtils.toByteArray(jarInputStream); 
       return new URL(null, "in-memory-bytes", new URLStreamHandler() { 
        @Override 
        protected URLConnection openConnection(URL u) throws IOException { 
         return new URLConnection(u) { 
          @Override 
          public void connect() throws IOException { 
           // nothing to do here 
          } 
          @Override 
          public InputStream getInputStream() throws IOException { 
           return new ByteArrayInputStream(bytes); 
          } 
         }; 
        } 
       }); 
      } 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 
Смежные вопросы