当前位置: 首页 > 知识库问答 >
问题:

Optaplanner项目的非法参数异常,解算器配置在类加载器中不作为类路径资源存在

戎高爽
2023-03-14

我得到一个错误时运行我的SpringBoot应用程序在我的求解器类。我试图从资源文件夹中包含的xml资源创建求解器工厂,就像OptaPlanner的员工名册示例一样,但我得到了一个非法参数异常,我不知道为什么。我试图将xml文件移动到与求解器类相同的文件夹中,但出现了相同的错误。我不知道为什么当我遵循OptaPlanner的员工名册示例代码时抛出异常?

下面是我的解算器类的代码:

package com.schedule.demo.solver;

import com.schedule.demo.domain.Roster;
import com.schedule.demo.service.RosterService;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;

import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.api.solver.SolverFactory;
import org.optaplanner.core.impl.score.director.ScoreDirector;
import org.optaplanner.core.impl.score.director.ScoreDirectorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.ApplicationScope;


@ApplicationScope
@Component
public class ScheduleSolverManager implements ApplicationRunner {

    public static final String SOLVER_CONFIG = "com/schedule/demo/service/solver/scheduleSolverConfig.xml";

    protected final transient Logger logger = LoggerFactory.getLogger(getClass());

    private SolverFactory<Roster> rosterSolverFactory;
    private ScoreDirectorFactory<Roster> rosterScoreDirectorFactory;

    private ThreadPoolTaskExecutor taskExecutor;

    private ConcurrentMap<Integer, Solver<Roster>> deptIdToSolverMap = new ConcurrentHashMap<>();

    private RosterService rosterService;

    public ScheduleSolverManager(ThreadPoolTaskExecutor taskExecutor, RosterService rosterService){
        this.taskExecutor = taskExecutor;
        this.rosterService = rosterService;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        setupRosterSolverFactory();
    }

    private void setupRosterSolverFactory() {
        rosterSolverFactory = SolverFactory.createFromXmlResource("com/schedule/demo/service/solver/scheduleSolverConfig.xml", ScheduleSolverManager.class.getClassLoader());
        rosterScoreDirectorFactory = rosterSolverFactory.buildSolver().getScoreDirectorFactory();
    }

    public CountDownLatch solve(Integer deptID){
        final CountDownLatch solvingEndedLatch = new CountDownLatch(1);
        try{
            taskExecutor.execute(()->{
                Solver<Roster> rosterSolver = rosterSolverFactory.buildSolver();
                deptIdToSolverMap.put(deptID, rosterSolver);
                rosterSolver.addEventListener(event -> {
                    if(event.isEveryProblemFactChangeProcessed()){
                        logger.info("New best solution found for deptId ({}).", deptID);
                        Roster newRoster = event.getNewBestSolution();
                        rosterService.updateShiftsOfRoster(newRoster);
                    }
                });
                Roster roster = rosterService.buildRoster(deptID);
                try {
                    rosterSolver.solve(roster);
                    solvingEndedLatch.countDown();
                }   finally {
                    deptIdToSolverMap.remove(deptID);
                }
            });
        } catch (Throwable e) {
            logger.error("Error solving for deptId (" + deptID + ").", e);
        }
        return solvingEndedLatch;
    }

    public Roster getRoster(final Integer deptId){
        Solver<Roster> rosterSolver = deptIdToSolverMap.get(deptId);
        return rosterSolver == null ? null : rosterSolver.getBestSolution();
    }

    public ScoreDirector<Roster> getScoreDirector() {
        return rosterScoreDirectorFactory.buildScoreDirector();
    }
}

运行时的错误如下所示:

Caused by: java.lang.IllegalArgumentException: The solverConfigResource (com/schedule/demo/service/solver/scheduleSolverConfig.xml) does not exist as a classpath resource in the classLoader (org.springframework.boot.devtools.restart.classloader.RestartClassLoader@2302b8ed).

共有2个答案

姚才捷
2023-03-14

为了能够将其作为类路径资源加载,您必须将求解器配置XML放在src/main/Resources下。

因此,如果使用资源名com/schedule/demo/service/solver/scheduleSolverConfig.xml加载它,那么文件必须位于

src/main/resources/com/schedule/demo/service/solver/scheduleSolverConfig.xml
卫阳曜
2023-03-14

使用optaplannerSpring启动启动器。它大大简化了Spring集成。

导游:https://github.com/spring-guides/getting-started-guides/pull/126

视频:https://www.youtube.com/watch?v=U2N02ReT9CI

如果您不想使用启动程序,这段代码可能会修复它:SolverFactory.createFromXmlResources("com/计划/演示/服务/解决方案/时间表SolverConfig.xml",Roster.class.getClassLoader());(使用名册的类加载器)。

 类似资料:
  • 问题内容: 假设我已经使用Groovyc编译了Groovy脚本,该脚本已在文件系统中生成了一个或多个.class文件。如何从Java应用程序动态地将这些类添加到类路径中,以加载它们并调用它们的方法?目标是预编译Groovy脚本并将其存储到数据库中,以便可以从脚本的编译版本执行评估。 问题答案: 您可以创建URLClassLoader的实例以从目录加载新类: 第1 行将.class 创建到.clas

  • 问题内容: 在关于类加载方法之间差异的一个流行答案中,乔恩·斯凯特(Jon Skeet)说, 类加载器资源路径始终被视为绝对路径。 一个更受欢迎的答案通过一个例子肯定了这一说法。 将所有路径视为绝对路径。因此,调用 和 都会在您的类路径中的以下位置查找文件: 。 忽略示例无法编译的事实,共识表明领先的正斜杠与ClassLoader无关。 一个简单的测试则相反。 我只是将路径添加到测试项目的类路径中

  • 问:什么是加载资源的正确解决方案(从类路径和/或一般情况下)?Spring文档中提倡使用:http://docs.Spring.io/Spring/docs/current/spring-framework-reference/html/beans.html#context-introduction 问:为什么autowired字段仍然为空?

  • 问题内容: 在Java中,您可以使用相同的API,但使用不同的URL协议来加载各种资源: 这很好地将资源的实际加载与需要资源的应用程序分离开来,并且由于URL只是一个字符串,因此资源加载也很容易配置。 是否有使用当前类加载器加载资源的协议?这类似于Jar协议,除了我不需要知道资源来自哪个jar文件或类文件夹。 我当然可以使用来做到这一点,但这需要我使用不同的API,因此需要对现有代码进行更改。我希

  • 我试图为我的项目设置配置位置,但我一直得到以下错误: java.io。FileNotFoundException:无法打开类路径资源[main/resources/app context.xml],因为它不存在 我的项目设置如下: 我将我的代码设置为: 我该怎么解决这个问题?

  • 我正在使用我的第一个spring helloworld程序,使用STS和maven,这是一个简单的IOC示例 和实现类 还有例外 L 它显示无法找到xml文件的位置,但我指定了我使用Spring工具套件mvc maven项目的位置