imagej / ij1-patcher

Extension points for ImageJ via runtime patching to support (limited) headless operation and ImageJ2's legacy layer
BSD 2-Clause "Simplified" License
5 stars 6 forks source link

VerifyError thrown when ij.jar is built targeting Java 1.8 #53

Open ctrueden opened 2 years ago

ctrueden commented 2 years ago

Even though ij1-patcher now successfully applies all its patches as of ImageJ 1.51p, the bytecode verifier still throws VerifyError if the ij.jar targets bytecode version 52 (i.e. Java 8) or later. This is discussed in #50. To avoid the problem, all releases of ij.jar are built targeting Java 6 bytecode, which is fine for now since ImageJ does not use any Java >6 APIs. But it restricts ImageJ from ever updating to a Java 8 minimum and using things like lambdas or the streaming API, which is unfortunate.

The proper thing would be to dig into why the bytecode verifier still dislikes the patched ImageJ classes, and address it, so that ImageJ patched by ij1-patcher + imagej-legacy is still considered valid by the Java runtime without needing a workaround like -Xverify:none.

imagesc-bot commented 2 years ago

This issue has been mentioned on Image.sc Forum. There might be relevant details there:

https://forum.image.sc/t/fiji-fails-to-launch-after-upgrade-to-imagej-daily-build/47125/8

ctrueden commented 2 years ago

From an ImageJ mailing list thread:

Fiji fails to launch if ImageJ is build for Java 8. This issue is discussed on the ImageJ.sc forum at https://forum.image.sc/t/fiji-fails-to-launch-after-upgrade-to-imagej-daily-build/47125 This is error message below that is generated: ``` [ERROR] Invalid service: net.imagej.legacy.LegacyService java.lang.VerifyError: Expecting a stack map frame Exception Details: Location: ij/IJ.getClassLoader()Ljava/lang/ClassLoader; @176: nop Reason: Expected stackmap frame at this location. Bytecode: 0x0000000: b20b 7501 a600 24b8 0059 b60b 78b3 0b75 0x0000010: b20b 7504 b80b 7c4b 2a01 a500 0eb8 0059 0x0000020: 2ab6 0b3b 2ab3 0b75 b20b 75b0 0000 00a7 0x0000030: fffd 0000 0000 00a7 fffb 0000 0000 0000 0x0000040: 0000 0000 0000 0000 0000 0000 a7ff ee00 0x0000050: 0000 0000 0000 a7ff f9a7 0000 0000 a7ff 0x0000060: fe00 0000 00a7 fffc 0000 0000 0000 00a7 0x0000070: fff9 0000 0000 0000 0000 0000 0000 0000 0x0000080: 0000 0000 a7ff ee00 0000 0000 0000 0000 0x0000090: 0000 0000 0000 0000 0000 0000 0000 0000 0x00000a0: 0000 0000 0000 0000 0000 0000 00a7 ffda 0x00000b0: 00bf 00a7 ffff 0000 0000 a7ff fc00 0000 0x00000c0: a7ff fd00 0000 0000 0000 0000 0000 00a7 0x00000d0: fff4 0000 0000 0000 0000 a7ff f800 a7ff 0x00000e0: ff Stackmap Table: same_frame(@40) same_frame(@44) same_frame(@50) same_frame(@58) same_frame(@79) same_frame(@89) same_frame(@92) same_frame(@97) same_frame(@104) same_frame(@114) same_frame(@135) same_frame(@178) same_frame(@182) same_frame(@189) same_frame(@195) same_frame(@210) same_frame(@221) at java.lang.Class.getDeclaredFields0(Native Method) at java.lang.Class.privateGetDeclaredFields(Class.java:2583) at java.lang.Class.getField0(Class.java:2975) at java.lang.Class.getField(Class.java:1701) at net.imagej.patcher.LegacyEnvironment.initialize(LegacyEnvironment.java:104) at net.imagej.patcher.LegacyEnvironment.applyPatches(LegacyEnvironment.java:494) at net.imagej.patcher.LegacyInjector.preinit(LegacyInjector.java:395) at net.imagej.patcher.LegacyInjector.preinit(LegacyInjector.java:374) at net.imagej.legacy.LegacyService.(LegacyService.java:141) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at java.lang.Class.newInstance(Class.java:442) at org.scijava.service.ServiceHelper.createServiceRecursively(ServiceHelper.java:300) at org.scijava.service.ServiceHelper.createExactService(ServiceHelper.java:267) at org.scijava.service.ServiceHelper.loadService(ServiceHelper.java:229) at org.scijava.service.ServiceHelper.loadService(ServiceHelper.java:192) at org.scijava.service.ServiceHelper.loadServices(ServiceHelper.java:164) at org.scijava.Context.(Context.java:285) at org.scijava.Context.(Context.java:234) at org.scijava.Context.(Context.java:174) at org.scijava.Context.(Context.java:160) at net.imagej.ImageJ.(ImageJ.java:77) at net.imagej.Main.main(Main.java:54) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.imagej.launcher.ClassLauncher.launch(ClassLauncher.java:279) at net.imagej.launcher.ClassLauncher.run(ClassLauncher.java:186) at net.imagej.launcher.ClassLauncher.main(ClassLauncher.java:87) [ERROR] No match: net.imagej.legacy.LegacyService [ERROR] Exception during event handling: [Event] org.scijava.service.event.ServicesLoadedEvent context = org.scijava.Context@3dcf75dd consumed = false [Subscriber] sc.fiji.compat.DefaultFijiService [priority = 0.0] [Method] protected void sc.fiji.compat.DefaultFijiService.onEvent(org.scijava.service.even ```
mkitti commented 2 years ago

There might be a hint here: https://github.com/powermock/powermock/pull/1043