Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from Java 11 LTS to Java 21 LTS #760

Merged
merged 20 commits into from
Oct 27, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
update to kryo 5, update dependencies
match dependencies to kryo-tools 1.5
network file version bumped to nv3
update r5 automatic module name
eliminate use of Integer constructor in response to deprecation warning
  • Loading branch information
abyrd committed Jan 18, 2023
commit 69cb79c9d71ed1125ba8d9f79fa995bc381e9c38
31 changes: 16 additions & 15 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ jar {
// Build-Jdk-Spec mimics a Maven manifest entry that helps us automatically install the right JVM.
// Implementation-X attributes are needed for ImageIO (used by Geotools) to initialize in some environments.
manifest {
attributes 'Automatic-Module-Name': 'com.conveyal.analysis',
attributes 'Automatic-Module-Name': 'com.conveyal.r5',
'Main-Class': 'com.conveyal.analysis.BackendMain',
'Build-Jdk-Spec': targetCompatibility.getMajorVersion(),
'Implementation-Title': 'Conveyal Analysis Backend',
@@ -31,15 +31,15 @@ jar {
}
}

// Allow reflective access by Kryo to normally closed Java internals.
// This is used for testing equality, but also for building automatic Kryo (de)serializers.
// Until we use the Java module system (add module-info.java) we also need to add these same flags to non-test runs.
// Allow reflective access by ObjectDiffer to normally closed Java internals. Used for round-trip testing serialization.
// IntelliJ seems not to pass these JVM arguments when running tests from within the IDE, so the Kryo serialization
// tests may only succeed under command line Gradle.
test {
useJUnitPlatform()
jvmArgs = ['--add-opens=java.base/java.io=ALL-UNNAMED',
'--add-opens=java.base/java.time=ALL-UNNAMED',
'--add-opens=java.base/java.time.zone=ALL-UNNAMED',
'--add-opens=java.base/java.lang=ALL-UNNAMED']
useJUnitPlatform()
}

// `gradle publish` will upload both shadow and simple JAR to Github Packages
@@ -127,6 +127,7 @@ repositories {
// Put Open Source Geospatial before Maven Central to get JAI core, see https://stackoverflow.com/a/26993223
maven { url 'https://repo.osgeo.org/repository/release/' }
mavenCentral()
mavenLocal()
// TODO review whether we really need the repositories below
maven { url 'https://maven.conveyal.com' }
// For the polyline encoder
@@ -140,10 +141,10 @@ configurations.all {

dependencies {
// Provides our logging API
implementation 'org.slf4j:slf4j-api:1.7.30'
implementation 'org.slf4j:slf4j-api:2.0.6'

// Implementation of the logging API
implementation 'ch.qos.logback:logback-classic:1.2.3'
implementation 'ch.qos.logback:logback-classic:1.4.5'

// Spark is an HTTP framework built on Jetty. Its name is the same as several other projects.
implementation (group: 'com.sparkjava', name: 'spark-core', version: '2.7.2') {
@@ -199,9 +200,6 @@ dependencies {
// Commons IO gives us BOMInputStream for handling UTF-8 Byte Order Marks.
implementation 'commons-io:commons-io:2.6'

// Guava provides a lot of functionality, collections, and tools "missing" from the Java standard library.
implementation 'com.google.guava:guava:28.2-jre'

// Java 8 rewrite of the Guava cache with asynchronous LoadingCaches. We don't currently use the async
// capabilities, but Caffeine's LoadingCache syntax is more modern idiomatic Java than Guava's.
implementation 'com.github.ben-manes.caffeine:caffeine:2.8.1'
@@ -218,15 +216,19 @@ dependencies {
// Commons Math gives us FastMath, MersenneTwister, and low-discrepancy vector generators.
implementation 'org.apache.commons:commons-math3:3.0'

// Provides some shared serializers for Kryo. Introduces transitive dependencies on Guava, Trove, and Kryo.
// Provides some Kryo serializers for Guava and Trove collecitons.
// Also provides classes for testing that a round trip through serialization reproduces the same network.
// This is an external dependency (not merged into backend) because it's also used by OTP2.
// TODO arguably we should declare non-transitive dependencies on Guava, Trove, and Kryo since we use them directly
implementation 'com.conveyal:kryo-tools:1.3.0'
implementation 'com.conveyal:kryo-tools:1.5.0'

// Ensure the versions of the next three dependencies match the transitive dependencies of kryo-tools.
implementation 'com.esotericsoftware:kryo:5.4.0'
// Guava provides a lot of functionality, collections, and tools "missing" from the Java standard library.
implementation 'com.google.guava:guava:31.1-jre'
// Trove supplies very efficient collections of primitive data types for Java.
implementation 'net.sf.trove4j:trove4j:3.0.3'


// TODO eliminate custom Conveyal geojson library, use Geotools?
implementation 'com.conveyal:jackson2-geojson:0.9'

@@ -249,8 +251,7 @@ dependencies {
////// Test-only dependencies //////

// Java unit testing framework.
testImplementation(platform('org.junit:junit-bom:5.7.0'))
testImplementation('org.junit.jupiter:junit-jupiter')
testImplementation('org.junit.jupiter:junit-jupiter:5.9.2')

// Chart drawing library for examining travel time distributions when crafting tests.
// Although rarely used it should be low-impact: it is a test-only dependency with no transitive dependenices.
16 changes: 11 additions & 5 deletions src/main/java/com/conveyal/r5/kryo/KryoNetworkSerializer.java
Original file line number Diff line number Diff line change
@@ -9,8 +9,9 @@
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.ExternalizableSerializer;
import com.esotericsoftware.kryo.serializers.ImmutableCollectionsSerializers;
import com.esotericsoftware.kryo.serializers.JavaSerializer;
import com.esotericsoftware.kryo.util.DefaultStreamFactory;
import com.esotericsoftware.kryo.util.DefaultInstantiatorStrategy;
import com.esotericsoftware.kryo.util.MapReferenceResolver;
import gnu.trove.impl.hash.TPrimitiveHash;
import gnu.trove.list.array.TIntArrayList;
@@ -43,13 +44,18 @@ public abstract class KryoNetworkSerializer {
* It should also be changed when the semantic content changes from that produced by earlier versions, even when
* the serialization format itself does not change. This will ensure newer workers will not load cached older files.
* We considered using an ISO date string as the version but that could get confusing when seen in filenames.
*
* History of Network Version (NV) changes:
* nv3 use Kryo 5 serialization format
* nv2 2022-04-05
* nv1 2021-04-30 stopped using r5 version string (which caused networks to be rebuilt for every new r5 version)
*/
public static final String NETWORK_FORMAT_VERSION = "nv2";
public static final String NETWORK_FORMAT_VERSION = "nv3";

public static final byte[] HEADER = "R5NETWORK".getBytes();

/** Set this to true to count instances and print a report including which serializer is handling each class. */
private static final boolean COUNT_CLASS_INSTANCES = false;
private static final boolean COUNT_CLASS_INSTANCES = true;

/**
* Factory method ensuring that we configure Kryo exactly the same way when saving and loading networks, without
@@ -61,7 +67,7 @@ public abstract class KryoNetworkSerializer {
private static Kryo makeKryo () {
Kryo kryo;
if (COUNT_CLASS_INSTANCES) {
kryo = new Kryo(new InstanceCountingClassResolver(), new MapReferenceResolver(), new DefaultStreamFactory());
kryo = new Kryo(new InstanceCountingClassResolver(), null);
} else {
kryo = new Kryo();
}
@@ -88,7 +94,7 @@ private static Kryo makeKryo () {
// The default strategy requires every class you serialize, even in your dependencies, to have a zero-arg
// constructor (which can be private). The setInstantiatorStrategy method completely replaces that default
// strategy. The nesting below specifies the Java approach as a fallback strategy to the default strategy.
kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy(new SerializingInstantiatorStrategy()));
kryo.setInstantiatorStrategy(new DefaultInstantiatorStrategy(new SerializingInstantiatorStrategy()));
return kryo;
}

4 changes: 2 additions & 2 deletions src/main/java/com/conveyal/r5/util/Histogram.java
Original file line number Diff line number Diff line change
@@ -111,9 +111,9 @@ public void displayHorizontal () {
row.append(' ');
}

String start = new Integer(minBin).toString();
String start = Integer.toString(minBin);
row.replace(0, start.length(), start);
String end = new Integer(maxBin).toString();
String end = Integer.toString(maxBin);
row.replace(row.length() - end.length(), row.length(), end);
System.out.println(row);
}