我的程序在我的IDE(IntelliJ)中工作正常,但出于某种原因,当我尝试创建一个jar文件时,从终端运行程序时出现以下错误:
线程中的异常" main" org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildDroolsScoreDirectorFactory(ScoreDirectorFactoryConfig.java:461)中的java.lang.NullPointerException
org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildScoreDirectorFactory(ScoreDirectorFactoryConfig.java:331)
org.optaplanner.core.config.solver.SolverConfig.buildSolver(SolverConfig.java:220)
org.optaplanner.core.impl.solver.AbstractSolverFactory.buildSolver(AbstractSolverFactory.java:57)
org.optaplanner.EmployeeRoster.main(EmployeeRoster.java:31)
这是我在EmployeeRoster中的第31行:
Solver solver = SolverFactory.createFromXmlResource(SOLVER_CONFIG_XML).buildSolver();
SOLVER_CONFIG_XML是一个String,包含我的XML solver-config的路径, 看起来像这样
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<solutionClass>org.optaplanner.solver.Roster</solutionClass>
<entityClass>org.optaplanner.domain.Assignment</entityClass>
<scoreDirectorFactory>
<scoreDrl>org/optaplanner/solver/employeeShiftsScoreRules.drl</scoreDrl>
</scoreDirectorFactory>
<localSearch>
<termination>
<secondsSpentLimit>5</secondsSpentLimit>
<bestScoreLimit>0hard/0medium/0soft</bestScoreLimit>
</termination>
<!--<termination>
<unimprovedStepCountLimit>5</unimprovedStepCountLimit>
</termination>-->
<acceptor>
<entityTabuSize>7</entityTabuSize>
</acceptor>
<forager>
<acceptedCountLimit>1000</acceptedCountLimit>
</forager>
</localSearch>
</solver>
&#13;
此处还有我的pom.xml文件,如果它应该是相关的:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
<groupId>org.btrg.dfb</groupId>
<artifactId>optaplanner</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-core</artifactId>
<version>7.3.0.Final</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.8</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>org.avalin.optaplanner.EmployeeRoster</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
我可能做错了什么?
答案 0 :(得分:4)
对我来说,问题必须处理我想要运行jar的方式( java -jar ),以及我如何构建jar。当我从 6.4.0 升级到 optaplanner-core / 7.4.1 时,出现NullPointerException。当我还在使用6.4.0时,这个问题不存在了。
例外:
显示java.lang.NullPointerException 在org.kie.internal.io.ResourceFactory.newByteArrayResource(ResourceFactory.java:66) at org.drools.compiler.kie.builder.impl.AbstractKieModule.getResource(AbstractKieModule.java:299) at org.drools.compiler.kie.builder.impl.AbstractKieModule.addResourceToCompiler(AbstractKieModule.java:264) at org.drools.compiler.kie.builder.impl.AbstractKieModule.addResourceToCompiler(AbstractKieModule.java:259) at org.drools.compiler.kie.builder.impl.AbstractKieProject.buildKnowledgePackages(AbstractKieProject.java:243) at org.drools.compiler.kie.builder.impl.AbstractKieProject.verify(AbstractKieProject.java:74) 在org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildKieProject(KieBuilderImpl.java:250) 在org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildAll(KieBuilderImpl.java:218) 在org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildAll(KieBuilderImpl.java:176) 在org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildDroolsScoreDirectorFactory(ScoreDirectorFactoryConfig.java:503)
以下是临时解决方法我解决NullPointerException并让应用程序运行。
dependencies {
...
compile group: 'org.optaplanner', name: 'optaplanner-core', version:'7.4.1.Final'
compile group: 'org.optaplanner', name: 'optaplanner-benchmark', version:'7.4.1.Final'
...
}
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'Self contained jar with all dependencies',
'Implementation-Version': version,
'Main-Class': 'path.to.class.with.main.method'
}
baseName = 'fatJar'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
unzip fatJar.jar -d unzippedJar/
“fatJar”任务压平了依赖项 - jar中允许使用重复的文件名。这导致了四个 unzippedJar / META-INF / kie.conf 文件,其中只使用了其中一个。无论使用哪个kie.conf文件,这都是我最后的kie.conf。
org.kie.api.internal.assembler.KieAssemblers = +org.optaplanner.core.impl.solver.kie.KieSolverAssemblerService
org.kie.api.internal.assembler.KieAssemblers = org.kie.internal.services.KieAssemblersImpl
org.kie.api.internal.runtime.KieRuntimes = org.kie.internal.services.KieRuntimesImpl
org.kie.api.internal.weaver.KieWeavers = org.kie.internal.services.KieWeaversImpl
org.kie.api.internal.runtime.beliefs.KieBeliefs = org.kie.internal.services.KieBeliefsImpl
org.kie.api.io.KieResources = org.drools.core.io.impl.ResourceFactoryServiceImpl
org.kie.api.marshalling.KieMarshallers = org.drools.core.marshalling.impl.MarshallerProviderImpl
org.kie.api.concurrent.KieExecutors = org.drools.core.concurrent.ExecutorProviderImpl
org.kie.api.KieServices = org.drools.compiler.kie.builder.impl.KieServicesImpl
org.kie.internal.builder.KnowledgeBuilderFactoryService = org.drools.compiler.builder.impl.KnowledgeBuilderFactoryServiceImpl
无论出于何种原因,指定MANIFEST.MF文件对我没有任何作用,因此我将其删除了。
jar cf rejard.jar .
java -cp rejard.jar path.to.class.with.main.method
答案 1 :(得分:2)
在@Arturo W的回答之后,我可以建议使用maven's assembly plugin进行另一种修复 制作一个胖子罐。
如documentation中所述:
”如果两个或多个元素(例如file,fileSet)选择了不同的来源 如果要归档同一文件,则仅归档其中一个源文件。 [...]阶段的顺序如下:1)FileItem 2)FileSets 3)ModuleSet 4)DependencySet和5)Repository元素。”
META-INF/kie.conf
位于org.optaplanner.core
的档案中,因此
Maven将optaplanner的版本打包到您定义的自定义版本中
存储库。
要包含此文件,我们在解包过程中会排除所有META-INF/kie.conf
个文件
并使用<file></file>
手动复制我们的版本
自定义描述符文件中的选项。
这是我们的操作方式:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- ... -->
<build>
<plugins>
<!-- ... -->
<!-- fat jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptors>
<descriptor>src/assembly/distribution.xml</descriptor>
</descriptors>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.veryseriouscompany.veryseriousproject.app.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>assemble-all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<!-- ... -->
要修复包含kie.conf
的问题,我们必须编写一个自定义描述符,
在src/assembly/distribution.xml
中定义。我们从预定义开始
描述符:
jar-with-dependencies。
这是一个很好的起点。
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>epigno-jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
<!-- Exclude all META-INF/kie.conf during unpacking -->
<unpackOptions>
<excludes>
<exclude>META-INF/kie.conf</exclude>
</excludes>
</unpackOptions>
</dependencySet>
</dependencySets>
<files>
<file>
<!-- Manually copy your custom kie configuration file from your repository. -->
<!-- Please replace this path by whatever path is relevant for your project. -->
<source>src/main/resources/META-INF/kie.conf</source>
<outputDirectory>META-INF</outputDirectory>
</file>
</files>
</assembly>
完成后,运行
mvn package
希望这会将正确的kie.conf
包装在您的胖子罐中!