Skip to content

Migrate build and runtime to Java 21 LTS#2903

Open
jhonesbr-jpva wants to merge 3 commits into
sepinf-inc:masterfrom
jhonesbr-jpva:java21-migration-upstream
Open

Migrate build and runtime to Java 21 LTS#2903
jhonesbr-jpva wants to merge 3 commits into
sepinf-inc:masterfrom
jhonesbr-jpva:java21-migration-upstream

Conversation

@jhonesbr-jpva

Copy link
Copy Markdown

Summary

Move the whole Maven reactor to Java 21 LTS (maven.compiler.release=21; build JDK is BellSoft Liberica Full 21 with JavaFX), preserving forensic behavior — no new language features were introduced, only the changes required to build and run on Java 21.

Changes

  • Strong encapsulation / SecurityManager: Bootstrap passes -Djava.security.manager=allow (required on Java 18+) and --add-exports java.desktop/{com.sun.imageio.plugins.common,sun.awt.image}=ALL-UNNAMED for the bundled PNG reader. StartUpControl reads the loaded-class count via ClassLoadingMXBean instead of reflecting on JDK internals.
  • RegexTask cache: removed the FST cache; RegexTask now uses JDK serialization with resilient reading of legacy caches.
  • Neo4j 4.4.4 → 5.26.0: the embedded engine now runs out-of-process over Bolt. A new module iped-graph-server hosts the engine + Cypher (antlr 4.13.2) isolated under lib/neo4j/, driven by neo4j-java-driver, while the main classpath keeps only neo4j-graphdb-api + the driver (still antlr 4.9.2 for libfqlite). Cypher queries updated to v5.
  • Dependency bumps: Jersey/HK2/Grizzly → 2.41, zstd-jni → 1.5.6-9.
  • Bundled JRE: ship Liberica Full 21.0.11 (java:jre Maven artifact); the Windows .exe launchers (iped.exe, IPED-SearchApp.exe) are rebuilt with launch4j (Windows-only profile) so they use the bundled jre/ instead of a registry-installed Java.
  • CI: replaced the Java 11/14 build matrix with a single Java 21 job (actions/setup-java@v4, Liberica, jdk+fx).

Notes

  • Forensic processing behavior is unchanged; the goal is purely the runtime/build migration to a current LTS.
  • The Neo4j engine is isolated in its own classloader/process to avoid antlr and dependency clashes with the rest of the application.

🤖 Generated with Claude Code

Move the whole Maven reactor to Java 21 (maven.compiler.release=21; build JDK
is BellSoft Liberica Full 21 with JavaFX), preserving forensic behavior (no
new language features).

- Strong encapsulation / SecurityManager: Bootstrap passes
  -Djava.security.manager=allow (required on Java 18+) and
  --add-exports java.desktop/{com.sun.imageio.plugins.common,sun.awt.image}=ALL-UNNAMED
  for the bundled PNG reader; StartUpControl reads the loaded-class count via
  ClassLoadingMXBean instead of reflecting on JDK internals.
- Remove the FST cache; RegexTask now uses JDK serialization with resilient
  reading of legacy caches.
- Upgrade Neo4j 4.4.4 -> 5.26.0 and run the embedded engine out-of-process
  over Bolt: new module iped-graph-server hosts the engine + Cypher (antlr
  4.13.2) isolated under lib/neo4j/, driven by neo4j-java-driver, while the
  main classpath keeps only neo4j-graphdb-api + the driver (still antlr 4.9.2
  for libfqlite). Cypher updated to v5.
- Dependency bumps: Jersey/HK2/Grizzly -> 2.41, zstd-jni -> 1.5.6-9.
- Bundle Liberica Full 21.0.11 JRE (java:jre Maven artifact); rebuild the
  Windows .exe launchers (iped.exe, IPED-SearchApp.exe) with launch4j
  (Windows-only profile) so they use the bundled jre/ instead of a registry
  Java.
- CI: replace the Java 11/14 matrix with a single Java 21 job
  (actions/setup-java@v4, Liberica, jdk+fx).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates the Maven reactor build/runtime baseline to Java 21 LTS, including CI, dependency updates, and a Neo4j redesign to avoid classpath conflicts by running Neo4j 5 out-of-process over Bolt.

Changes:

  • Switch build baseline to Java 21 (maven.compiler.release=21), update Maven plugin versions, and update CI to a single Java 21 Liberica (JavaFX) job.
  • Rework graph subsystem: upgrade Neo4j to 5.26 and run the embedded engine in a dedicated child JVM (iped-graph-server) with an isolated lib/neo4j/ stack; main process uses Bolt driver + neo4j-graphdb-api snapshots.
  • Replace/adjust Java 11-era APIs/internals (e.g., JAXB DatatypeConverter, reflective classloader access), remove FST cache in RegexTask, and add required --add-exports / SecurityManager flags.

Reviewed changes

Copilot reviewed 38 out of 41 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
ThirdParty.txt Updates third-party inventory (adds Neo4j/Jersey/ANTLR/launch4j, updates zstd-jni version).
ReleaseNotes.txt Adds 4.4.0 TBD notes describing the Java 21 + Neo4j changes.
pom.xml Sets Java 21 via maven.compiler.release and adds the new iped-graph-server module.
iped-viewers/pom.xml Updates compiler + surefire plugin versions for Java 21 builds.
iped-utils/pom.xml Updates dependency plugin version.
iped-utils/.settings/org.eclipse.jdt.apt.core.prefs Enables Eclipse APT settings for generated sources.
iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/telegram/TelegramParser.java Replaces JAXB Base64 decoding with java.util.Base64.
iped-parsers/iped-parsers-impl/pom.xml Updates JNA; updates surefire + JaCoCo for Java 21 and adds test JVM exports.
iped-graph-server/src/main/java/iped/engine/graph/server/GraphServer.java New child JVM entry point hosting Neo4j 5 over Bolt.
iped-graph-server/src/main/java/iped/engine/graph/server/GraphPostImport.java New child JVM post-import runner for Cypher statements + contact grouping.
iped-graph-server/src/assembly/neo4j.xml Assembly descriptor to bundle the isolated Neo4j runtime into a zip.
iped-graph-server/pom.xml New module POM: pulls full Neo4j engine and assembles the distribution zip.
iped-graph-server/.gitignore Ignores build + IDE artifacts for the new module.
iped-geo/pom.xml Updates compiler + surefire plugin versions for Java 21 builds.
iped-engine/src/main/java/iped/engine/util/Util.java Updates supported Java version range to 21..21.
iped-engine/src/main/java/iped/engine/task/regex/RegexTask.java Removes FST cache and switches to JDK serialization with legacy-cache tolerance.
iped-engine/src/main/java/iped/engine/task/ImageThumbTask.java Adds debug log with exception when thumbnail generation times out.
iped-engine/src/main/java/iped/engine/graph/Neo4jChildLauncher.java New helper to build child JVM command lines for isolated Neo4j stack.
iped-engine/src/main/java/iped/engine/graph/links/SearchLinksQuery.java Updates query SPI to use GraphService (Bolt-backed) instead of embedded DB access.
iped-engine/src/main/java/iped/engine/graph/links/AbstractSearchLinksQuery.java Routes link queries through GraphService.searchPaths(...).
iped-engine/src/main/java/iped/engine/graph/GraphServiceImpl.java Replaces embedded Neo4j with child GraphServer process + Bolt driver; adds snapshot adapters.
iped-engine/src/main/java/iped/engine/graph/GraphService.java Removes getGraphDb() and adds searchPaths(...) entry point for SPI queries.
iped-engine/src/main/java/iped/engine/graph/GraphImportRunner.java Runs neo4j-admin database import full in an isolated child JVM.
iped-engine/src/main/java/iped/engine/graph/GraphGenerator.java Runs post-import work in an isolated child JVM (instead of embedded engine).
iped-engine/src/main/java/iped/engine/graph/BoltRelationship.java New read-only Relationship snapshot wrapper for Bolt results.
iped-engine/src/main/java/iped/engine/graph/BoltPath.java New read-only Path snapshot wrapper for Bolt results.
iped-engine/src/main/java/iped/engine/graph/BoltNode.java New read-only Node snapshot wrapper for Bolt results (includes degree snapshot).
iped-engine/src/main/java/iped/engine/graph/BoltEntity.java New base snapshot wrapper implementing Entity.
iped-engine/pom.xml Updates zstd-jni + Jersey; replaces embedded Neo4j dep with graphdb-api + driver; removes FST.
iped-carvers/pom.xml Updates compiler + surefire plugin versions for Java 21 builds.
iped-app/src/main/java/iped/app/ui/splash/StartUpControl.java Replaces reflective class count with ClassLoadingMXBean.
iped-app/src/main/java/iped/app/timelinegraph/cache/persistance/CachePersistance.java Replaces JAXB hex encoding with HexFormat for Java 21.
iped-app/src/main/java/iped/app/timelinegraph/cache/CacheTimePeriodEntry.java Removes Scala array dependency; uses System.arraycopy.
iped-app/src/main/java/iped/app/graph/SearchLinksWorker.java Uses GraphService instead of embedded GraphDatabaseService for link searches.
iped-app/src/main/java/iped/app/bootstrap/Bootstrap.java Adds Java 21 runtime flags for SecurityManager and required --add-exports.
iped-app/resources/config/conf/GraphConfig.json Updates index creation Cypher to Neo4j 5 syntax (CREATE INDEX IF NOT EXISTS FOR ...).
iped-app/pom.xml Bundles Liberica 21 JRE; unpacks isolated Neo4j zip; updates plugins; adds Windows launch4j profile.
.github/workflows/maven.yml Updates CI to Java 21 Liberica (JavaFX) with Maven cache; removes 11/14 matrix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread iped-engine/src/main/java/iped/engine/graph/BoltEntity.java
Comment thread iped-engine/src/main/java/iped/engine/graph/BoltRelationship.java
Comment thread iped-engine/src/main/java/iped/engine/graph/GraphGenerator.java
jhonesbr-jpva and others added 2 commits June 24, 2026 17:36
Two pre-existing bugs in the contact-grouping step, ported verbatim from the
old GraphGenerator into GraphPostImport during the Java 21 migration:

- Evidence nodes were added to the `inputs` map instead of `evidences`,
  leaving the group's `groupedIds` empty and reversing the group->evidence
  edge direction.
- The last contact group of each label was never created: createGroup only
  ran on a contact change inside the loop, so the trailing group was dropped.
  It is now flushed after the loop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- BoltEntity.getProperty now throws NotFoundException for absent keys,
  matching the org.neo4j.graphdb.Entity contract. Callers such as
  GraphModel.getLabel rely on it to probe candidate fields; returning null
  surfaced downstream as a NullPointerException.
- GraphGenerator.runChild now propagates a non-zero child exit code as an
  IOException instead of only logging it, so a failed post-import (missing
  indexes / contact grouping) no longer reports overall success.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 38 out of 41 changed files in this pull request and generated 9 comments.

Comment on lines +439 to 450
StringBuilder queryBuilder = new StringBuilder();
queryBuilder.append("MATCH (n:").append(label.name()).append(") ");
if (!params.isEmpty()) {
queryBuilder.append(" WHERE ");
Iterator<String> iterator = params.keySet().iterator();
while (iterator.hasNext()) {
String name = iterator.next();
queryBuilder.append(" n.").append(name);
if (iterator.hasNext()) {
queryBuilder.append(" AND ");
}
}
Comment on lines +98 to +102
private int readBoltPort(Process process) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
int port = -1;
String line;
while ((line = reader.readLine()) != null) {
Comment on lines 94 to 98
File emptyConf = new File(System.getProperty("java.io.tmpdir"), "neo4j.conf");
if (!emptyConf.exists()) {
emptyConf.createNewFile();
}
emptyConf.deleteOnExit();
Comment on lines +75 to +77
GraphDatabaseService db = dms.database(dbName);
db.isAvailable(30000);

Comment on lines +65 to +67
GraphDatabaseService db = dms.database(dbName);
db.isAvailable(30000);

Comment on lines 247 to 251
int listLen = dis.readInt();
byte[] list = new byte[listLen];
dis.readFully(list);
regexList = (List<Regex>) fastSerializer.asObject(list);
regexList = (List<Regex>) deserialize(list);
int fullLen = dis.readInt();
Comment on lines +274 to +276
private static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
return ois.readObject();
Comment thread iped-app/pom.xml
Comment on lines +42 to +47
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
Comment thread iped-graph-server/pom.xml
Comment on lines +48 to +51
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants