rcsb / symmetry

:ferris_wheel: Detect, analyze, and visualize protein symmetry
GNU Lesser General Public License v2.1
26 stars 16 forks source link

CeSymm broken on many java versions #104

Closed sbliven closed 2 years ago

sbliven commented 2 years ago

Biojava and cesymm officially support Java 1.8+. However the CeSymm jar file includes many dependencies which break this compatiblity.

Java 8

❌ Broken due to jgrapht

java -jar 'symmetry-tools/target/CeSymm-2.2.0-SNAPSHOT.jar' 1tim.A
Structure       NumRepeats      SymmGroup       Reason
Exception in thread "pool-2-thread-1" java.lang.UnsupportedClassVersionError: org/jgrapht/Graph has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:473)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
        at workers.CeSymmWorker.run(CeSymmWorker.java:65)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

Jgrapht dropped java 8 support after 1.3.0, so BioJava needs to pin that version upstream.

Java 11

⚠️ Works, but warnings:

java -jar 'symmetry-tools/target/CeSymm-2.2.0-SNAPSHOT.jar' 1tim.A
WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance.
Structure       NumRepeats      SymmGroup       Reason
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector (file:/Users/bliven_s/git/biojava_ws/symmetry/symmetry-tools/target/CeSymm-2.2.0-SNAPSHOT.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int)
WARNING: Please consider reporting this to the maintainers of com.sun.xml.bind.v2.runtime.reflect.opt.Injector
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
1tim.A  2       C2      Significant (TM=0,56)

com.sun.xml was removed in Java 11. BioJava gets around this by bundling it as a dependency, but the warnings indicate the bundled JAXB version is not fully compatible.

Java 15 and 17

❌ Broken

java -jar 'symmetry-tools/target/CeSymm-2.2.0-SNAPSHOT.jar' 1tim.A
WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance.
Structure       NumRepeats      SymmGroup       Reason
Nov 10, 2021 9:43:22 PM com.sun.xml.bind.v2.runtime.reflect.opt.Injector <clinit>
SEVERE: null
java.security.PrivilegedActionException: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:573)
        at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.<clinit>(Injector.java:166)
        at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:51)
        at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:157)
        at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:255)
        at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.<init>(SingleElementLeafProperty.java:62)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
        at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:99)
        at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:150)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:493)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:512)
        at com.sun.xml.bind.v2.runtime.ArrayBeanInfoImpl.<init>(ArrayBeanInfoImpl.java:48)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:502)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:304)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:109)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1142)
        at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:141)
        at com.sun.xml.bind.v2.JAXBContextFactory.createContext(JAXBContextFactory.java:35)
        at javax.xml.bind.ContextFinder.find(ContextFinder.java:404)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
        at org.biojava.nbio.structure.xtal.io.SpaceGroupMapRoot.fromXML(SpaceGroupMapRoot.java:77)
        at org.biojava.nbio.structure.xtal.SymoplibParser.parseSpaceGroupsXML(SymoplibParser.java:140)
        at org.biojava.nbio.structure.xtal.SymoplibParser.parseSpaceGroupsXML(SymoplibParser.java:104)
        at org.biojava.nbio.structure.xtal.SymoplibParser.<clinit>(SymoplibParser.java:58)
        at org.biojava.nbio.structure.io.cif.CifStructureConsumerImpl.consumeSymmetry(CifStructureConsumerImpl.java:1099)
        at org.biojava.nbio.structure.io.cif.CifStructureConverter.fromCifFile(CifStructureConverter.java:156)
        at org.biojava.nbio.structure.io.cif.CifStructureConverter.fromInputStream(CifStructureConverter.java:83)
        at org.biojava.nbio.structure.io.BcifFileReader.getStructure(BcifFileReader.java:41)
        at org.biojava.nbio.structure.io.LocalPDBDirectory.getStructureById(LocalPDBDirectory.java:349)
        at org.biojava.nbio.structure.align.util.AtomCache.loadStructureFromBcifByPdbId(AtomCache.java:893)
        at org.biojava.nbio.structure.align.util.AtomCache.getStructureForPdbId(AtomCache.java:831)
        at org.biojava.nbio.structure.SubstructureIdentifier.loadStructure(SubstructureIdentifier.java:324)
        at org.biojava.nbio.structure.align.client.StructureName.loadStructure(StructureName.java:517)
        at org.biojava.nbio.structure.align.util.AtomCache.getStructure(AtomCache.java:503)
        at workers.CeSymmWorker.run(CeSymmWorker.java:58)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
        at java.base/java.lang.Class.getMethod(Class.java:2227)
        at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:170)
        at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:166)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
        ... 42 more

Exception in thread "pool-2-thread-1" java.lang.ExceptionInInitializerError
        at org.biojava.nbio.structure.io.cif.CifStructureConsumerImpl.consumeSymmetry(CifStructureConsumerImpl.java:1099)
        at org.biojava.nbio.structure.io.cif.CifStructureConverter.fromCifFile(CifStructureConverter.java:156)
        at org.biojava.nbio.structure.io.cif.CifStructureConverter.fromInputStream(CifStructureConverter.java:83)
        at org.biojava.nbio.structure.io.BcifFileReader.getStructure(BcifFileReader.java:41)
        at org.biojava.nbio.structure.io.LocalPDBDirectory.getStructureById(LocalPDBDirectory.java:349)
        at org.biojava.nbio.structure.align.util.AtomCache.loadStructureFromBcifByPdbId(AtomCache.java:893)
        at org.biojava.nbio.structure.align.util.AtomCache.getStructureForPdbId(AtomCache.java:831)
        at org.biojava.nbio.structure.SubstructureIdentifier.loadStructure(SubstructureIdentifier.java:324)
        at org.biojava.nbio.structure.align.client.StructureName.loadStructure(StructureName.java:517)
        at org.biojava.nbio.structure.align.util.AtomCache.getStructure(AtomCache.java:503)
        at workers.CeSymmWorker.run(CeSymmWorker.java:58)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.reflect.Method.invoke(Object, Object[])" because "com.sun.xml.bind.v2.runtime.reflect.opt.Injector.defineClass" is null
        at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Injector.java:294)
        at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Injector.java:66)
        at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:57)
        at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:157)
        at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:255)
        at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.<init>(SingleElementLeafProperty.java:62)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
        at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:99)
        at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:150)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:493)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:512)
        at com.sun.xml.bind.v2.runtime.ArrayBeanInfoImpl.<init>(ArrayBeanInfoImpl.java:48)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:502)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:304)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:109)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1142)
        at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:141)
        at com.sun.xml.bind.v2.JAXBContextFactory.createContext(JAXBContextFactory.java:35)
        at javax.xml.bind.ContextFinder.find(ContextFinder.java:404)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
        at org.biojava.nbio.structure.xtal.io.SpaceGroupMapRoot.fromXML(SpaceGroupMapRoot.java:77)
        at org.biojava.nbio.structure.xtal.SymoplibParser.parseSpaceGroupsXML(SymoplibParser.java:140)
        at org.biojava.nbio.structure.xtal.SymoplibParser.parseSpaceGroupsXML(SymoplibParser.java:104)
        at org.biojava.nbio.structure.xtal.SymoplibParser.<clinit>(SymoplibParser.java:58)
        ... 14 more

XML parsing seems completely broken with the bundled JAXB. The code runs fine for me in VSCode, so I believe the problem is introduced in the shade step, which includes dependencies without stringent compatibility checks.

josemduarte commented 2 years ago

I suppose you are using the latest biojava release (6.0.0)?

Also another comment, have you tried the explicit dependencies solution for this project? I.e. what this PR did for biojava: https://github.com/biojava/biojava/pull/805/files

sbliven commented 2 years ago

@josemduarte I need to look into it more, but I think that PR probably broke it for Java 15. CeSymm uses mvn shade, so all of biojava's dependencies get pulled recursively including the JAXB implementation.

The protein-comparison-tool also uses shade and is also broken on java 15, although it gives a different exception.

I think the solution to this is probably to switch biojava to use a different XML implementation.

sbliven commented 2 years ago

The glassfish implementation fixed the problem. Should be fixed after merging biojava/biojava#996 upstream

sbliven commented 2 years ago

Fixed in #112 with biojava 6.0.3