1

我有一个在自定义 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)

我正在创建这样的类加载器:

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

如您所见,它设法加载第一部分,然后在 LWJGL 版本之后突然崩溃,并出现“input == null”。

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

图片

代码:

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

    return url;
}
4

2 回答 2

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); }
}
于 2012-04-12T13:36:34.410 回答
0

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

很可能 ClassLoader 很快就被黑客入侵以进行测试,而将更复杂的方法排除在外。

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

实现一个不简单委托给现有 ClassLoader 的完全工作的 ClassLoader 并不像大多数示例看起来那样简单。

于 2012-04-12T16:59:56.217 回答