2012-04-12 2 views
1

У меня есть загрузчик класса памяти (here), который я использую в пользовательской пусковой установке Minecraft.Java MemoryClassLoader (IllegalArgumentException)

Memory Class Loader

Всякий раз, когда я загрузить Minecraft (игра Java LWJGL), я получаю следующее сообщение об ошибке:

27 achievements 
182 recipes 
Setting user 
LWJGL Version: 2.4.2 
java.lang.IllegalArgumentException: input == null! 
at javax.imageio.ImageIO.read(Unknown Source) 
at lc.<init>(SourceFile:21) 
at gi.<init>(SourceFile:10) 
at net.minecraft.client.Minecraft.a(SourceFile:254) 
at net.minecraft.client.Minecraft.run(SourceFile:657) 
at java.lang.Thread.run(Unknown Source) 

я создаю загрузчик классов, как это:

Base.cLoader = new CLoader(
    GameUpdater.classLoader, 
    new JarInputStream(new ByteArrayInputStream(jarFileBytes))); 

Как вы можете видеть, ему удается загрузить первую часть, а затем внезапно после LWJ GL с ошибкой «input == null».

Редактировать - вот новый метод getResource.
Ошибка указана на «URL()», как показано на рисунке.

Image

Код:

public URL getResource(final String name) { 
    URL url = new URL() { public InputStream openStream() { 
     return new ByteArrayInputStream((byte[])others.get(name)); 
    }}; 

    return url; 
} 

ответ

2

Грубое предположение ... это может быть так: Внимание: URL-адреса для этого еще не реализованы! Вы не можете вызвать getResource() или getResources()!

Таким образом, ваш код ожидает получить изображение из JAR с использованием не реализованного метода. Эквивалент этого, вероятно, выполняется:

ImageIO.read(memClassLoader.getResource(someString)); 

Кроме того, что, как мы уже видели, ошибка выброшен из getResource становится игнорироваться и null используется в качестве значения. ImageIO.read выглядит следующим образом:

public static BufferedImage read(URL input) throws IOException { 
    if (input == null) { 
     throw new IllegalArgumentException("input == null!"); 
    } 

    InputStream istream = null; 
    try { 
     istream = input.openStream(); 
    } catch (IOException e) { 
     throw new IIOException("Can't get input stream from URL!", e); 
    } 
} 

Звучит знакомо? Итак, это примерно то, что вам нужно реализовать:

public URL getResource(final String name) { 
    try { 
    return new URL("", "", 0, "", 
     new URLStreamHandler() { public URLConnection openConnection(URL url) { 
      return new URLConnection(url) { 
      public void connect() {} 
      public InputStream getInputStream() { 
       // return the appropriate InputStream, based on the name arg 
      } 
      }; 
     }}); 
    } catch (MalformedURLException e) { throw new RuntimeException(e); } 
} 
+0

Я попробую добавить пользовательский метод «getResource», тогда ... вы можете быть абсолютно прав! Ха-ха. –

+0

У меня возникли проблемы с созданием метода getResource(), поскольку я понятия не имею, с чего начать. Есть идеи? –

+0

Отредактирован ответ. –

0

MemoryClassLoader в значительной степени сломан. Он не реализует getResource() (как указано в комментарии в источнике), а также не определяет пакеты для классов, которые он загружает (это может или не может разорвать приложение).

Скорее всего, ClassLoader был быстро взломан для тестирования, оставив более сложные методы.

Реализация собственного протокола URL для обработки getResource() не слишком сложна, в getResource() вы возвращаете URL-адрес, который использует имя пользовательского протокола (например, «myclassloader: // resourcename»), а также пользовательскую реализацию URLStreamHandler, который обрабатывает этот протокол. Это может не охватывать все лазейки, которые могут вызвать проблемы при поиске ресурса, если код, загруженный через ClassLoader, использует URL.toString() и преобразует его обратно, он все равно сломается.

Реализация полнофункционального ClassLoader, который не является простым делегированием существующим ClassLoaders, не так прост, как это делает большинство примеров.

+0

Интересно, есть ли примеры этого? Я совершенно не знаком с сценой ClassLoader. Мне бы очень хотелось получить работу MemoryClassLoader, хотя, если это будет сложно, мне просто придется загружать его в обычном режиме. :/ –

+0

Я не знаю каких-либо полностью работающих примеров - я взломал свой собственный ClassLoader и, скорее всего, все еще не обрабатывал все возможные варианты использования. При тестировании я столкнулся с проблемами getResource() и «без пакетов», оба из которых нарушили приложение, которое мне нужно было запустить. – Durandal

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

  • Нет связанных вопросов^_^