为什么在使用 proguard 混淆时调用不起作用

Why does invoke not work when using proguard obfuscation

我有一个用于 Minecraft 的 Fabric 1.17.1 (Java 16) mod,我正在尝试对其进行混淆。 mod 中包含我的事件系统,它处理我的 mod 的所有事件。此事件系统使用 invoke 方法在 运行 时间调用我的事件侦听器 class 中的事件。

这是我使用调用方法调用的事件:

@EventHandler
public static void onMinecraftInitialization(EventMinecraftInitialization event)
{
    // Do stuff
}

调用方法如下:

public void call(Event event)
{
    final EventData data = get(event.getClass());

    try
    {
        data.target.invoke(data.source, event); // Error here
    }
    catch (InvocationTargetException | IllegalAccessException e)
    {
        e.printStackTrace();
    }
}

我也在使用 mixins 来注册我的事件侦听器 class,效果很好。

在开发环境中,这工作正常,我的 minecraft mod 运行s。但是,当我构建 mod 并尝试在 Minecraft 启动器中使用它时,它崩溃了,崩溃报告为:

java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    dev/mistercow1/sobyity/EventBus.call(Ldev/mistercow1/sobyity/Event;)V @33: invokevirtual
  Reason:
    Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 
    'java/lang/ReflectiveOperationException'

dev/mistercow1/sobyity/EventBus.call(Ldev/mistercow1/sobyity/Event;)V @33是我调用方法中的invoke。

更正:dev/mistercow1/sobyity/EventBus.call(Ldev/mistercow1/sobyity/Event;)V @33e.printStackTrace();

在我的 proguard 映射中,我排除了事件库和 mixin 包(因此它们不会被混淆),因为这是 minecraft 到 运行 所必需的,因为它是使用 shadowjar 打包到 jar 中的.我还禁用了收缩和优化,并将 classes 重新打包到基本目录中 (dev.mistercow1.minecraftmod)

在我的 mod 的去混淆版本和开发环境中一切正常,所以我很困惑为什么混淆版本不起作用。

我已经试过用data.target.invoke(null, event);代替,但是没有效果。

这是我的事件系统或 minecraft 的问题 mod 还是 proguard 的问题?

有人对此有任何解决方案吗?

编辑:对事件包使用 -keep 是无效的,因为我没有使用 Method m = ReflectMethodinvokeExample1.class.getDeclaredMethod("process", String.class); 之类的东西来查找要调用的方法。

我通过将 C:\Program Files\Java\jdk-16.0.2\jmods 中的所有 jmod 添加到 -libraryjars 来解决这个问题,例如:

-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.base.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.compiler.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.datatransfer.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.desktop.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.instrument.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.logging.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.management.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.management.rmi.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.naming.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.net.http.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.prefs.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.rmi.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.scripting.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.se.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.security.jgss.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.security.sasl.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.smartcardio.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.sql.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.sql.rowset.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.transaction.xa.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.xml.crypto.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\java.xml.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.accessibility.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.attach.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.charsets.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.compiler.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.crypto.cryptoki.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.crypto.ec.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.crypto.mscapi.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.dynalink.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.editpad.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.hotspot.agent.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.httpserver.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.incubator.foreign.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.incubator.vector.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.internal.ed.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.internal.jvmstat.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.internal.le.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.internal.opt.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.internal.vm.ci.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jartool.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.javadoc.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jcmd.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jconsole.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jdeps.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jdi.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jdwp.agent.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jfr.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jlink.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jpackage.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jshell.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jsobject.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.jstatd.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.localedata.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.management.agent.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.management.jfr.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.management.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.naming.dns.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.naming.rmi.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.net.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.nio.mapmode.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.sctp.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.security.auth.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.security.jgss.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.unsupported.desktop.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.unsupported.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.xml.dom.jmod'
-libraryjars 'C:\Program Files\Java\jdk-16.0.2\jmods\jdk.zipfs.jmod'

编辑:只需将其放入 build.gradle:

的混淆任务中
fileTree("${System.properties['java.home']}\jmods\") {
    forEach() {
        libraryjars "${it.path}"
    }
}