Home > Enterprise >  Can run in Intellij, but jar file fails
Can run in Intellij, but jar file fails

Time:05-02

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.

  • Related