Java MemoryClassLoader(IllegalArgumentException)

Java MemoryClassLoader(IllegalArgumentException),java,class,memory,loader,encryption,Java,Class,Memory,Loader,Encryption,我有一个内存类加载器(),我在一个定制的Minecraft启动器中使用它 每当我加载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.<

我有一个内存类加载器(),我在一个定制的Minecraft启动器中使用它


每当我加载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)
正如您所看到的,它成功地加载了第一部分,然后在LWJGL版本之后,它突然崩溃,出现“input==null”

编辑-这里是新的getResource方法。
错误出现在“URL()”上,如图所示

代码:


胡乱猜测。。。可能是这样的:警告:此URL尚未实现!不能调用getResource()或getResources()

因此,您的代码希望使用未实现的方法从JAR检索图像。可能正在执行类似的操作:

ImageIO.read(memClassLoader.getResource(someString));
除此之外,正如我们所看到的,从
getResource
抛出的错误被忽略,并且
null
被用作值。是这样的:

Base.cLoader = new CLoader(
    GameUpdater.classLoader,
    new JarInputStream(new ByteArrayInputStream(jarFileBytes)));
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); }
}

MemoryClassLoader几乎坏了。它没有实现getResource()(如源代码中的注释所述),也没有为它加载的类定义包(这可能会破坏应用程序,也可能不会破坏应用程序)

最有可能的是,ClassLoader很快被黑客攻击用于测试目的,而忽略了更复杂的方法

实现您自己的URL协议来处理getResource()并不太困难,在getResource()中,您返回一个使用自定义协议名称(例如“mycl”)的URLassloader://resourcename)以及处理该协议的URLStreamHandler的自定义实现。 这可能无法覆盖所有可能导致查找资源时出现问题的漏洞,如果通过类加载器加载的代码使用URL.toString()并将其转换回,它仍然会中断


实现一个完全工作的类加载器,而不是简单地委托给现有的类加载器,并不像大多数示例看起来那么简单。

我将尝试添加一个自定义的“getResource”方法。。。你可能完全正确!哈哈。我在创建实际的getResource()方法时遇到了麻烦,因为我不知道从哪里开始。有什么想法吗?是的,它在错误消息之前就被调用了。问题肯定出在getResource()方法上。只是,我不知道从这一点上我能做些什么。它写在注释“请注意,您不能-*获取类文件作为资源(URL或流)。”那么我们如何获取资源URL:你引用的评论不是问题所在。您无法获取类文件,但您可以获取其他所有内容——这就是类文档所说的,这就是您可以在
getResourceAsStream
中看到的情况。至于实现
getResource
。。。注意,它返回的是一个URL,而不是资源的实际内容。评论中已经有了一些提示…用更多的想法更新了答案。有趣的是,有这样做的例子吗?我对类加载器的场景是完全陌生的。我真的很想让MemoryClassLoader工作,尽管如果它很难,那么我只能正常加载它/我不知道有任何完全有效的例子——我黑了自己的类加载器,很可能仍然不能处理所有可能的用例。在测试时,我遇到了getResource()和“未定义包”问题,这两个问题都破坏了我需要运行的应用程序。
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); }
}