Instead of running Quarkus
, I’m running OptaPlanner through a Main class
entry point in Kotlin
.
This works great within Intellij
where I have a simple Run Configuration
set up for it.
object Main { lateinit var solverFactory: SolverFactory<VehicleRoutingSolution> lateinit var solver: Solver<VehicleRoutingSolution> lateinit var scoreManager: ScoreManager<VehicleRoutingSolution, SimpleLongScore> @JvmStatic fun main(args: Array<String>) { ...
However, when I create an Intellij artifact
for a jar
and try to run it, I get this:
java -jar acme.jar Apr. 28, 2022 5:21:13 P.M. 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:484) at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:301) at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:109) at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1126) at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:135) at com.sun.xml.bind.v2.JAXBContextFactory.createContext(JAXBContextFactory.java:35) at javax.xml.bind.ContextFinder.find(ContextFinder.java:393) at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:691) at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:632) at org.optaplanner.core.impl.io.jaxb.GenericJaxbIO.<init>(GenericJaxbIO.java:88) at org.optaplanner.core.impl.io.jaxb.GenericJaxbIO.<init>(GenericJaxbIO.java:80) at org.optaplanner.core.impl.io.jaxb.SolverConfigIO.<init>(SolverConfigIO.java:27) at org.optaplanner.core.config.solver.SolverConfig.createFromXmlReader(SolverConfig.java:213) at org.optaplanner.core.config.solver.SolverConfig.createFromXmlInputStream(SolverConfig.java:188) at org.optaplanner.core.config.solver.SolverConfig.createFromXmlResource(SolverConfig.java:128) at org.optaplanner.core.config.solver.SolverConfig.createFromXmlResource(SolverConfig.java:103) at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:55) at org.acme.bootstrap.Main.initOptaPlanner(Main.kt:112) at org.acme.bootstrap.Main.main(Main.kt:43) 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) ... 31 more Exception in thread "main" 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:484) at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:301) at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:109) at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1126) at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:135) at com.sun.xml.bind.v2.JAXBContextFactory.createContext(JAXBContextFactory.java:35) at javax.xml.bind.ContextFinder.find(ContextFinder.java:393) at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:691) at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:632) at org.optaplanner.core.impl.io.jaxb.GenericJaxbIO.<init>(GenericJaxbIO.java:88) at org.optaplanner.core.impl.io.jaxb.GenericJaxbIO.<init>(GenericJaxbIO.java:80) at org.optaplanner.core.impl.io.jaxb.SolverConfigIO.<init>(SolverConfigIO.java:27) at org.optaplanner.core.config.solver.SolverConfig.createFromXmlReader(SolverConfig.java:213) at org.optaplanner.core.config.solver.SolverConfig.createFromXmlInputStream(SolverConfig.java:188) at org.optaplanner.core.config.solver.SolverConfig.createFromXmlResource(SolverConfig.java:128) at org.optaplanner.core.config.solver.SolverConfig.createFromXmlResource(SolverConfig.java:103) at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:55) at org.acme.bootstrap.Main.initOptaPlanner(Main.kt:112) at org.acme.bootstrap.Main.main(Main.kt:43) Shutting down
In solverConfig.xml
I’m using <domainAccessType>REFLECTION</domainAccessType>
because I cannot get Gizmo
to work. I’m not sure if that’s related or not, but why is there a difference between an Intellij Run Config
and the Jar
artifact?
Thanks
*** UPDATE ***
I still get the above error message – even when creating a very basic OptaPlanner project.
Here is my pom.xml file:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>foo</artifactId> <groupId>org.acme</groupId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>Foo</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <kotlin.version>1.6.21</kotlin.version> <kotlin.code.style>official</kotlin.code.style> <kotlin.compiler.jvmTarget>17</kotlin.compiler.jvmTarget> <optaplanner.version>8.20.0.Final</optaplanner.version> </properties> <repositories> <repository> <id>mavenCentral</id> <url>https://repo1.maven.org/maven2/</url> </repository> </repositories> <build> <finalName>foo</finalName> <sourceDirectory>src/main/kotlin</sourceDirectory> <testSourceDirectory>src/test/kotlin</testSourceDirectory> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> <executions> <execution> <id>compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.3.0</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>org.acme.bootstrap.Main</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencyManagement> <dependencies> <dependency> <groupId>org.optaplanner</groupId> <artifactId>optaplanner-bom</artifactId> <type>pom</type> <version>${optaplanner.version}</version> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-jdk8</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>org.optaplanner</groupId> <artifactId>optaplanner-core</artifactId> </dependency> </dependencies> </project>
Here’s what I run with Maven:
mvn clean compile package java -jar ./target/foo-jar-with-dependencies.jar
Note: I’m using openjdk-17.0.2
java --version openjdk 17.0.2 2022-01-18 OpenJDK Runtime Environment (build 17.0.2+8-86) OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)
It still runs fine within IntelliJ’s system, but from Maven it just throws the above error.
Also, here’s my solverConfig.xml
for reference.
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <solver xmlns="https://www.optaplanner.org/xsd/solver"> <solutionClass>org.acme.domain.MySolution</solutionClass> <entityClass>org.acme.domain.Visit</entityClass> <scoreDirectorFactory> <constraintProviderClass>org.acme.solver.MyConstraintProvider</constraintProviderClass> </scoreDirectorFactory> <termination> <millisecondsSpentLimit>2000</millisecondsSpentLimit> </termination> </solver>
And my Main.kt
file:
object Main { lateinit var solverFactory: SolverFactory<MySolution> lateinit var solver: Solver<MySolution> lateinit var scoreManager: ScoreManager<MySolution, SimpleLongScore> @JvmStatic fun main(args: Array<String>) { solverFactory = SolverFactory.createFromXmlResource("solverConfig.xml") solver = solverFactory.buildSolver() scoreManager = ScoreManager.create(solverFactory) } }
Advertisement
Answer
An answer to another question suggests you need an extra artifact in your project. Technically, optaplanner-core
module brings it, but the scope is runtime
– so that dependency may not show up in the JAR with dependencies. (?) You will need to include it yourself; you can confirm that by checking mvn dependency:tree
in your project.
That said, I am not sure why we use the runtime
scope here. Maybe we need to re-evaluate.
Also, seeing as you are using an uberjar, I’m going to point to another uberjar-related question to perhaps pre-empt more struggle.