Skip to content

Commit 523d316

Browse files
authored
feat: convert solver to JPMS (TimefoldAI#2149)
1 parent 504bab1 commit 523d316

107 files changed

Lines changed: 959 additions & 507 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ CI checks enforce those conventions too, so be sure to build your project with M
9191
./mvnw clean install
9292
```
9393

94-
For information about how to set up code style checks in your IDE, see [IDE Setup Instructions](https://github.com/TimefoldAI/timefold-solver/blob/main/build/ide-config/ide-configuration.adoc).
94+
For information about how to set up code style checks in your IDE, see [IDE Setup Instructions](build/ide-config/ide-configuration.adoc).
9595

9696
**Key code style conventions** (see [Constitution](.specify/memory/constitution.md) for complete details):
9797
- Automatic formatting via Maven build

build/bom/pom.xml

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,6 @@
4848
<type>test-jar</type>
4949
<version>${version.ai.timefold.solver}</version>
5050
</dependency>
51-
<dependency>
52-
<groupId>ai.timefold.solver</groupId>
53-
<artifactId>timefold-solver-persistence-common</artifactId>
54-
<version>${version.ai.timefold.solver}</version>
55-
</dependency>
56-
<dependency>
57-
<groupId>ai.timefold.solver</groupId>
58-
<artifactId>timefold-solver-persistence-common</artifactId>
59-
<version>${version.ai.timefold.solver}</version>
60-
<classifier>sources</classifier>
61-
</dependency>
62-
<dependency>
63-
<groupId>ai.timefold.solver</groupId>
64-
<artifactId>timefold-solver-persistence-common</artifactId>
65-
<type>test-jar</type>
66-
<version>${version.ai.timefold.solver}</version>
67-
</dependency>
6851
<dependency>
6952
<groupId>ai.timefold.solver</groupId>
7053
<artifactId>timefold-solver-jaxb</artifactId>

build/build-parent/pom.xml

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<version.org.apache.logging.log4j>2.25.3</version.org.apache.logging.log4j>
2727
<version.org.assertj>3.27.7</version.org.assertj>
2828
<version.org.awaitility>4.3.0</version.org.awaitility>
29+
<version.org.eclipse.microprofile.config>3.1.1-RC1</version.org.eclipse.microprofile.config>
2930
<version.org.freemarker>2.3.34</version.org.freemarker>
3031
<version.org.jfree.jfreechart>1.5.6</version.org.jfree.jfreechart>
3132
<version.org.jspecify>1.0.0</version.org.jspecify>
@@ -60,9 +61,6 @@
6061
<!-- Plugin configuration properties -->
6162
<maven.min.version>3.9.11</maven.min.version> <!-- The same as the version in .mvn/maven-wrapper.properties -->
6263
<maven.compiler.release>21</maven.compiler.release>
63-
<!-- This property needs to be defined in all modules that use the packaging 'jar'.
64-
It is used by different plugins to make sure the module/bundle names are consistent. -->
65-
<java.module.name/>
6664
<spotless.skip>false</spotless.skip>
6765
<spotless.goal>apply</spotless.goal>
6866
<!-- JaCoCo coverage data file location -->
@@ -369,16 +367,6 @@
369367
<artifactId>maven-jar-plugin</artifactId>
370368
<version>${version.jar.plugin}</version>
371369
<executions>
372-
<execution>
373-
<id>default-jar</id>
374-
<configuration>
375-
<archive>
376-
<manifestEntries combine.children="append">
377-
<Automatic-Module-Name>${java.module.name}</Automatic-Module-Name>
378-
</manifestEntries>
379-
</archive>
380-
</configuration>
381-
</execution>
382370
<execution>
383371
<id>test-jar</id>
384372
<goals>
@@ -454,6 +442,28 @@
454442
<compilerArgument>-Xlint:none</compilerArgument>
455443
</compilerArgs>
456444
</configuration>
445+
<executions>
446+
<execution>
447+
<id>default-compile</id>
448+
<phase>compile</phase>
449+
<goals>
450+
<goal>compile</goal>
451+
</goals>
452+
<!-- no useModulePath override here -->
453+
</execution>
454+
455+
<!-- test compile: force classpath (no module-path) -->
456+
<execution>
457+
<id>default-testCompile</id>
458+
<phase>test-compile</phase>
459+
<goals>
460+
<goal>testCompile</goal>
461+
</goals>
462+
<configuration>
463+
<useModulePath>false</useModulePath>
464+
</configuration>
465+
</execution>
466+
</executions>
457467
</plugin>
458468
<plugin>
459469
<groupId>org.jacoco</groupId>
@@ -568,13 +578,17 @@
568578
<artifactId>maven-surefire-plugin</artifactId>
569579
<version>${version.surefire.plugin}</version>
570580
<configuration>
581+
<!-- Currently not running on the module path, despite including JPMS -->
582+
<useModulePath>false</useModulePath>
571583
<redirectTestOutputToFile>true</redirectTestOutputToFile>
572584
</configuration>
573585
</plugin>
574586
<plugin>
575587
<artifactId>maven-failsafe-plugin</artifactId>
576588
<version>${version.surefire.plugin}</version>
577589
<configuration>
590+
<!-- Currently not running on the module path, despite including JPMS -->
591+
<useModulePath>false</useModulePath>
578592
<redirectTestOutputToFile>true</redirectTestOutputToFile>
579593
</configuration>
580594
<executions>

build/ide-config/ide-configuration.adoc

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
= IDE code style setup
1+
= Configuring your IDE for Timefold Solver
2+
3+
== Running tests in your IDE
4+
5+
Timefold Solver is https://en.wikipedia.org/wiki/Java_Platform_Module_System[a modular project].
6+
However, its test coverage runs on the classpath, not the module path.
7+
Maven respects this and runs the tests on the classpath, but IDEs don't always do that by default.
8+
If you're running your tests in the IDE and seeing errors about missing modules,
9+
you need to configure your IDE to run the tests on the classpath.
10+
11+
== IDE code style setup
212

313
Every Maven build formats the source code with the standard code style.
414
This avoids merge conflicts and code style discussions.
515

616
Configure it in your favorite IDE too:
717

8-
== IDEA setup
18+
=== IDEA setup
919

1020
. Open the _Settings_ window (or _Preferences_ depending on your edition) and navigate to _Plugins_.
1121

@@ -26,7 +36,7 @@ file in the `build/ide-config/src/main/resources/` directory.
2636

2737
. Open the _Editor -> Code Style -> Java -> Imports_ settings and set the _Class count to use import with '\*'_ to 999. This is to avoid the `*` imports, which should only be used in special cases.
2838

29-
== Eclipse setup
39+
=== Eclipse setup
3040

3141
. Open the _Preferences_ window, and then navigate to _Java -> Code Style -> Formatter_.
3242

@@ -36,7 +46,7 @@ file in the `build/ide-config/src/main/resources/` directory.
3646

3747
. Click Import and select the `build/ide-config/src/main/resources/eclipse.importorder` file.
3848

39-
== VS Code setup
49+
=== VS Code setup
4050

4151
. Open the _Extensions_ window (Ctrl+Shift+X) and search for _Language Support for Java(TM)_ and install it.
4252

build/ide-config/pom.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,4 @@
2020
</description>
2121
<url>https://solver.timefold.ai</url>
2222

23-
<properties>
24-
<java.module.name>ai.timefold.solver.ide.config</java.module.name>
25-
</properties>
26-
2723
</project>

core/pom.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@
2222
</description>
2323
<url>https://solver.timefold.ai</url>
2424

25-
<properties>
26-
<java.module.name>ai.timefold.solver.core</java.module.name>
27-
</properties>
28-
2925
<dependencies>
3026

3127
<!-- Gizmo dependencies -->

persistence/common/src/main/java/ai/timefold/solver/persistence/common/api/domain/solution/SolutionFileIO.java renamed to core/src/main/java/ai/timefold/solver/core/api/domain/solution/SolutionFileIO.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
package ai.timefold.solver.persistence.common.api.domain.solution;
1+
package ai.timefold.solver.core.api.domain.solution;
22

33
import java.io.File;
44

5-
import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
6-
75
/**
86
* Reads or writes a {@link PlanningSolution} from or to a {@link File}.
97
* <p>

core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/factory/MoveIteratorFactoryConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import ai.timefold.solver.core.config.heuristic.selector.move.MoveSelectorConfig;
1010
import ai.timefold.solver.core.config.util.ConfigUtils;
1111
import ai.timefold.solver.core.impl.heuristic.selector.move.factory.MoveIteratorFactory;
12-
import ai.timefold.solver.core.impl.io.jaxb.adapter.JaxbCustomPropertiesAdapter;
12+
import ai.timefold.solver.core.impl.io.jaxb.JaxbCustomPropertiesAdapter;
1313

1414
import org.jspecify.annotations.NonNull;
1515
import org.jspecify.annotations.Nullable;
@@ -25,7 +25,7 @@ public class MoveIteratorFactoryConfig extends MoveSelectorConfig<MoveIteratorFa
2525
protected Class<? extends MoveIteratorFactory> moveIteratorFactoryClass = null;
2626

2727
@XmlJavaTypeAdapter(JaxbCustomPropertiesAdapter.class)
28-
protected Map<String, String> moveIteratorFactoryCustomProperties = null;
28+
protected @Nullable Map<String, String> moveIteratorFactoryCustomProperties = null;
2929

3030
public @Nullable Class<? extends MoveIteratorFactory> getMoveIteratorFactoryClass() {
3131
return moveIteratorFactoryClass;

core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/factory/MoveListFactoryConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import ai.timefold.solver.core.config.heuristic.selector.move.MoveSelectorConfig;
1010
import ai.timefold.solver.core.config.util.ConfigUtils;
1111
import ai.timefold.solver.core.impl.heuristic.selector.move.factory.MoveListFactory;
12-
import ai.timefold.solver.core.impl.io.jaxb.adapter.JaxbCustomPropertiesAdapter;
12+
import ai.timefold.solver.core.impl.io.jaxb.JaxbCustomPropertiesAdapter;
1313

1414
import org.jspecify.annotations.NonNull;
1515
import org.jspecify.annotations.Nullable;

core/src/main/java/ai/timefold/solver/core/config/partitionedsearch/PartitionedSearchPhaseConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import ai.timefold.solver.core.config.phase.PhaseConfig;
1717
import ai.timefold.solver.core.config.phase.custom.CustomPhaseConfig;
1818
import ai.timefold.solver.core.config.util.ConfigUtils;
19-
import ai.timefold.solver.core.impl.io.jaxb.adapter.JaxbCustomPropertiesAdapter;
19+
import ai.timefold.solver.core.impl.io.jaxb.JaxbCustomPropertiesAdapter;
2020
import ai.timefold.solver.core.impl.partitionedsearch.partitioner.SolutionPartitioner;
2121

2222
import org.jspecify.annotations.NonNull;

0 commit comments

Comments
 (0)