Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f0ce2ed
Update version string to '4.0.0-SNAPSHOT'.
jenetics Nov 7, 2023
75d5d7e
Remove Java 17 from build.
jenetics Nov 7, 2023
b48a91e
#174: Update to Java 21.
jenetics Nov 7, 2023
f35146e
#174: Update compiler warning flags.
jenetics Nov 7, 2023
62a2ede
#174: Extract version catalog to toml file.
jenetics Nov 7, 2023
eaa3bfe
#174: Use Javadoc code snippets.
jenetics Nov 7, 2023
5eaa9fc
#174: Remove unused plugin.
jenetics Nov 7, 2023
87be51d
#174: Improve Javadoc.
jenetics Nov 7, 2023
aaf2335
Merge pull request #176 from jenetics/issues/JPX-174-Java21
jenetics Nov 7, 2023
407040d
#177: Convert 'geom' classes to records.
jenetics Nov 7, 2023
db19f84
#177: Refactor to sealed types.
jenetics Nov 7, 2023
4120445
Merge pull request #178 from jenetics/issues/JPX-177-Convert_'geom'_c…
jenetics Nov 7, 2023
1dc1e39
Update version placeholder.
jenetics Nov 8, 2023
204c335
Improve Javadoc.
jenetics Nov 8, 2023
f6307ac
Merge branch 'master' into releases/r4.0.0
jenetics Nov 16, 2024
db19cd0
Update used libraries.
jenetics Nov 16, 2024
8ca1e95
Update Gradle to 9.0.
jenetics Aug 24, 2025
9c09015
Update dependency management.
jenetics Aug 24, 2025
d7bd5af
Update gradle.yml
jenetics Aug 24, 2025
97af57a
Upgrade publishing scripts.
jenetics Aug 24, 2025
eb93090
Merge branch 'master' into releases/r4.0.0
jenetics Aug 24, 2025
fac2d4b
#192: Update Gradle to 9.3.1.
jenetics Feb 22, 2026
0ce640a
#192: Update libraries.
jenetics Feb 22, 2026
eb90d8e
#192: Update to Java 25.
jenetics Feb 22, 2026
d307d04
#192: Remvove 'obj == this' from equals methods.
jenetics Feb 22, 2026
d3197cb
#192: Some code cleanup.
jenetics Feb 22, 2026
5c86a55
#192: Update version number.
jenetics Feb 22, 2026
575efd2
#192: Update README.
jenetics Feb 22, 2026
e1abab3
#192: Update GitHub Actions for Gradle build process
jenetics Feb 22, 2026
858b729
Merge pull request #193 from jenetics/issues/JPX-192-java_25
jenetics Feb 22, 2026
88309a2
Update README.
jenetics Feb 22, 2026
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
49 changes: 25 additions & 24 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
name: JPX Build

on:
push:
branches:
- master
- releases/*
- issues/*
pull_request:
branches:
- master
- releases/*
push:
branches:
- master
- releases/*
- issues/*
pull_request:
branches:
- master
- releases/*

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, macos-latest ]
java-version: [ 17, 21, 23 ]
steps:
- uses: actions/checkout@v2
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, macos-latest ]
java-version: [ 25 ]
steps:
- uses: actions/checkout@v4

- name: Set up JDK ${{ matrix.java-version }} on ${{ matrix.os }}
uses: actions/setup-java@v2
with:
java-version: ${{ matrix.java-version }}
distribution: 'zulu'
- name: Build with Gradle
run: ./gradlew build --stacktrace --info
- name: Set up JDK ${{ matrix.java-version }} on ${{ matrix.os }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java-version }}
distribution: 'zulu'
cache: 'gradle'
- name: Build with Gradle
run: ./gradlew build --stacktrace --info
65 changes: 8 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
# JPX

![Build Status](https://github.com/jenetics/jpx/actions/workflows/gradle.yml/badge.svg)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.jenetics/jpx/badge.svg)](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jpx%22)
[![Maven Central Version](https://img.shields.io/maven-central/v/io.jenetics/jpx?color=green)](https://central.sonatype.com/artifact/io.jenetics/jpx)
[![Javadoc](https://www.javadoc.io/badge/io.jenetics/jpx.svg)](http://www.javadoc.io/doc/io.jenetics/jpx)

**JPX** is a Java library for creating, reading and writing [GPS](https://en.wikipedia.org/wiki/Global_Positioning_System) data in [GPX](https://en.wikipedia.org/wiki/GPS_Exchange_Format) format. It is a *full* implementation of version [1.1](http://www.topografix.com/GPX/1/1/) and version [1.0](http://www.topografix.com/gpx_manual.asp) of the GPX format. The data classes are completely immutable and allows a functional programming style. They are working also nicely with the Java [Stream](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/stream/Stream.html) API. It is also possible to convert the location information into strings which are compatible to the [ISO 6709](http://en.wikipedia.org/wiki/ISO_6709) standard.

**JPX** is a Java library for creating, reading and writing [GPS](https://en.wikipedia.org/wiki/Global_Positioning_System) data in [GPX](https://en.wikipedia.org/wiki/GPS_Exchange_Format) format. It is a *full* implementation of version [1.1](http://www.topografix.com/GPX/1/1/) and version [1.0](http://www.topografix.com/gpx_manual.asp) of the GPX format. The data classes are completely immutable and allows a functional programming style. They are working also nicely with the Java [Stream](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/stream/Stream.html) API. It is also possible to convert the location information into strings which are compatible to the [ISO 6709](http://en.wikipedia.org/wiki/ISO_6709) standard.

Besides the basic functionality of reading and writing GPX files, the library also allows manipulating the read GPX object in a functional way.


## Dependencies

The _JPX_ library needs no external dependencies. It only needs **Java 17** to compile and run. It also runs and compiles with **Java 21** and **Java 23**.
The _JPX_ library needs no external dependencies. It needs **Java 25** to compile and run.


## Building JPX
Expand Down Expand Up @@ -314,7 +315,7 @@ org.acme.NonValidatingDocumentBuilder

The library is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).

Copyright 2016-2025 Franz Wilhelmstötter
Copyright 2016-2026 Franz Wilhelmstötter

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -330,62 +331,12 @@ The library is licensed under the [Apache License, Version 2.0](http://www.apach

## Release notes

### [3.2.1](https://github.com/jenetics/jpx/releases/tag/v3.2.1)

#### Improvements

* [#186](https://github.com/jenetics/jpx/issues/186): LENIENT mode allows GPX tags without creator attributes.

### [3.2.0](https://github.com/jenetics/jpx/releases/tag/v3.2.0)

#### Improvements

* [#183](https://github.com/jenetics/jpx/issues/183): Update Gradle to 8.11 and improve build scripts.
* [#181](https://github.com/jenetics/jpx/pull/181): Update code examples in README.

### [3.1.0](https://github.com/jenetics/jpx/releases/tag/v3.1.0)
### [4.0.0](https://github.com/jenetics/jpx/releases/tag/v4.0.0)

#### Improvements

* [#170](https://github.com/jenetics/jpx/issues/170): GPX files with invalid version number are now readable in _LENIENT_ mode.
```java
final GPX gpx;
try (InputStream in = new FileInputStream(resource)) {
gpx = GPX.Reader.of(Mode.LENIENT).read(in);
}
```

#### Bugs

* [#167](https://github.com/jenetics/jpx/issues/167): Fixing a test case for Windows.

### [3.0.1](https://github.com/jenetics/jpx/releases/tag/v3.0.1)

#### Bugs
* [#177](https://github.com/jenetics/jpx/issues/177): Convert 'geom' classes to records.
* [#192](https://github.com/jenetics/jpx/issues/192): Update library to Java 25.

* [#162](https://github.com/jenetics/jpx/issues/162): Elevation serialization for values > 1000m is incompatible with deserialization.

### [3.0.0](https://github.com/jenetics/jpx/releases/tag/v3.0.0)

#### Improvements

* [#125](https://github.com/jenetics/jpx/issues/125): **Breaking change** - Use `Instant` instead of `ZonedDateTime` for `Point.time` property.
* [#148](https://github.com/jenetics/jpx/issues/148): **Breaking change** - Update to Java17.
* [#155](https://github.com/jenetics/jpx/issues/155): Improved `GPX.Reader` and `GPX.Writer` classes.
* [#158](https://github.com/jenetics/jpx/issues/158): Add XML `Document` reader/writer methods.
```java
final GPX gpx = ...;

final Document doc = XMLProvider.provider()
.documentBuilderFactory()
.newDocumentBuilder()
.newDocument();

// The GPX data are written to the empty `doc` object.
GPX.Writer.DEFAULT.write(gpx, new DOMResult(doc));
```

#### Bugs

* [#151](https://github.com/jenetics/jpx/issues/151): `Double`'s being written as exponents in GPX file.
* [#152](https://github.com/jenetics/jpx/issues/152): `LocationFormatter::parse` method is not thread-safe.
114 changes: 46 additions & 68 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import io.jenetics.gradle.dsl.isModule
import io.jenetics.gradle.dsl.moduleName
import org.apache.tools.ant.filters.ReplaceTokens

/*
* Java GPX Library (@__identifier__@).
Expand All @@ -9,7 +10,7 @@ import io.jenetics.gradle.dsl.moduleName
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
Expand All @@ -18,7 +19,7 @@ import io.jenetics.gradle.dsl.moduleName
* limitations under the License.
*
* Author:
* Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
* Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
*/

/**
Expand All @@ -28,13 +29,13 @@ import io.jenetics.gradle.dsl.moduleName
*/
plugins {
base
id("me.champeau.jmh") version "0.7.2" apply false
alias(libs.plugins.version.catalog.update)
}

rootProject.version = JPX.VERSION

tasks.named<Wrapper>("wrapper") {
version = "8.11"
version = "9.3.1"
distributionType = Wrapper.DistributionType.ALL
}

Expand Down Expand Up @@ -71,8 +72,8 @@ gradle.projectsEvaluated {

plugins.withType<JavaPlugin> {
configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_25
targetCompatibility = JavaVersion.VERSION_25
}

configure<JavaPluginExtension> {
Expand Down Expand Up @@ -132,7 +133,7 @@ fun setupTestReporting(project: Project) {
project.apply(plugin = "jacoco")

project.configure<JacocoPluginExtension> {
toolVersion = "0.8.12"
toolVersion = libs.jacoco.agent.get().version.toString()
}

project.tasks {
Expand Down Expand Up @@ -169,13 +170,12 @@ fun setupJavadoc(project: Project) {
doclet.charSet = "UTF-8"
doclet.linkSource(true)
doclet.linksOffline(
"https://docs.oracle.com/en/java/javase/17/docs/api/",
"https://docs.oracle.com/en/java/javase/25/docs/api/",
"${project.rootDir}/buildSrc/resources/javadoc/java.se"
)
doclet.windowTitle = "JPX ${project.version}"
doclet.docTitle = "<h1>JPX ${project.version}</h1>"
doclet.bottom = "&copy; ${Env.COPYRIGHT_YEAR} Franz Wilhelmst&ouml;tter &nbsp;<i>(${Env.BUILD_DATE})</i>"
doclet.stylesheetFile = project.file("${project.rootDir}/buildSrc/resources/javadoc/stylesheet.css")

doclet.tags = listOf(
"apiNote:a:API Note:",
Expand All @@ -193,38 +193,6 @@ fun setupJavadoc(project: Project) {
}
}
}

val javadoc = project.tasks.findByName("javadoc") as Javadoc?
if (javadoc != null) {
project.tasks.register<io.jenetics.gradle.ColorizerTask>("colorizer") {
directory = javadoc.destinationDir!!
}

project.tasks.register("java2html") {
doLast {
providers.javaexec {
mainClass.set("de.java2html.Java2Html")
args = listOf(
"-srcdir", "src/main/java",
"-targetdir", "${javadoc.destinationDir}/src-html/${project.extra["moduleName"]}"
)
classpath = files("${project.rootDir}/buildSrc/lib/java2html.jar")
}
}
}

javadoc.doLast {
val colorizer = project.tasks.findByName("colorizer")
colorizer?.actions?.forEach {
it.execute(colorizer)
}

val java2html = project.tasks.findByName("java2html")
java2html?.actions?.forEach {
it.execute(java2html)
}
}
}
}

/**
Expand All @@ -242,13 +210,18 @@ fun xlint(): String {
"empty",
"exports",
"finally",
"lossy-conversions",
"module",
"opens",
"overrides",
"rawtypes",
"removal",
"serial",
// "serial",
"static",
"strictfp",
"synchronization",
"text-blocks",
"this-escape",
"try",
"unchecked",
"varargs"
Expand All @@ -257,6 +230,9 @@ fun xlint(): String {

val identifier = "${JPX.ID}-${JPX.VERSION}"

/**
* Setup of the Maven publishing.
*/
/**
* Setup of the Maven publishing.
*/
Expand All @@ -268,26 +244,29 @@ fun setupPublishing(project: Project) {

project.tasks.named<Jar>("sourcesJar") {
filter(
org.apache.tools.ant.filters.ReplaceTokens::class, "tokens" to mapOf(
"__identifier__" to identifier,
"__year__" to Env.COPYRIGHT_YEAR
)
ReplaceTokens::class, "tokens" to mapOf(
"__identifier__" to identifier,
"__year__" to Env.COPYRIGHT_YEAR
)
)
}

project.tasks.named<Jar>("javadocJar") {
filter(
org.apache.tools.ant.filters.ReplaceTokens::class, "tokens" to mapOf(
"__identifier__" to identifier,
"__year__" to Env.COPYRIGHT_YEAR
)
ReplaceTokens::class, "tokens" to mapOf(
"__identifier__" to identifier,
"__year__" to Env.COPYRIGHT_YEAR
)
)
}

project.configure<PublishingExtension> {
publications {
create<MavenPublication>("mavenJava") {
artifactId = JPX.ID
suppressPomMetadataWarningsFor("testFixturesApiElements")
suppressPomMetadataWarningsFor("testFixturesRuntimeElements")

artifactId = project.name
from(project.components["java"])
versionMapping {
usage("java-api") {
Expand Down Expand Up @@ -327,24 +306,23 @@ fun setupPublishing(project: Project) {
}
repositories {
maven {
url = if (version.toString().endsWith("SNAPSHOT")) {
uri(Maven.SNAPSHOT_URL)
} else {
uri(Maven.RELEASE_URL)
}
url = if (version.toString().endsWith("SNAPSHOT"))
uri(layout.buildDirectory.dir("repos/snapshots"))
else
uri(layout.buildDirectory.dir("repos/releases"))
}
}

credentials {
username = if (extra.properties["nexus_username"] != null) {
extra.properties["nexus_username"] as String
} else {
"nexus_username"
}
password = if (extra.properties["nexus_password"] != null) {
extra.properties["nexus_password"] as String
} else {
"nexus_password"
}
}
// Exclude test fixtures from publication, as we use them only internally
plugins.withId("org.gradle.java-test-fixtures") {
val component = components["java"] as AdhocComponentWithVariants
component.withVariantsFromConfiguration(configurations["testFixturesApiElements"]) { skip() }
component.withVariantsFromConfiguration(configurations["testFixturesRuntimeElements"]) { skip() }

// Workaround to not publish test fixtures sources added by com.vanniktech.maven.publish plugin
// TODO: Remove as soon as https://github.com/vanniktech/gradle-maven-publish-plugin/issues/779 closed
afterEvaluate {
component.withVariantsFromConfiguration(configurations["testFixturesSourcesElements"]) { skip() }
}
}
}
Expand Down
11 changes: 0 additions & 11 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,3 @@ repositories {
mavenLocal()
gradlePluginPortal()
}

tasks.withType<KotlinCompile> {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
}
}

configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
Loading