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)
}
}
CodePudding user response:
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.