Merge pull request #419 from mswatosh/2.2-updates Modernization updates
diff --git a/.github/ISSUE_TEMPLATE/tck_challenge.md b/.github/ISSUE_TEMPLATE/tck_challenge.md new file mode 100644 index 0000000..05b69fb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/tck_challenge.md
@@ -0,0 +1,21 @@ +--- +name: TCK Challenge +about: Create a TCK Challenge +title: '' +labels: 'challenge' +assignees: '' + +--- + +**Challenged tests** +List the challenged tests with the fully qualified classnames and then the test methods, e.g. +ee.jakarta.tck.jsonp.api.jsonnumbertests.ClientTests#jsonNumberEqualsTest + +**TCK Version** +Specify the version of the TCK, e.g. Jakarta JSON Processing 2.1.x + +**Description** +A clear and concise description of why you think the tests are wrong. + +**Additional context** +Add any other context about the challenge here.
diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml new file mode 100644 index 0000000..5c7ed41 --- /dev/null +++ b/.github/workflows/performance.yml
@@ -0,0 +1,57 @@ +# +# Copyright (c) 2026 Eclipse Foundation and/or its affiliates. All rights reserved. +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Public License v. 2.0 which is available at +# http://www.eclipse.org/legal/epl-2.0, +# or the Eclipse Distribution License v. 1.0 which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +# + +name: Performance + +on: + schedule: + # Runs every Thursday at 4:35 AM UTC (avoid peak hours for better performance results) + - cron: '35 4 * * 4' + workflow_dispatch: + +jobs: + performance: + name: Run JMH performance tests + runs-on: ubuntu-latest + + steps: + - name: Checkout for performance + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + - name: Set up compile JDK + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 + with: #Compile java needs to be the highest to ensure proper compilation of the multi-release jar + distribution: 'temurin' + java-version: 17 + cache: 'maven' + - name: Compile API + run: | + mvn -U -C clean install --file api/pom.xml + - name: Run JMH performance tests + run: | + cd perf + mvn -U -B clean package + java -jar target/jsonp-jmh.jar -rf json -rff jmh-result.json + - name: Persist JMH results + uses: benchmark-action/github-action-benchmark@52576c92bccf6ac60c8223ec7eb2565637cae9ba # v1.22.1 + with: + name: Java JMH Benchmark + tool: 'jmh' + output-file-path: perf/jmh-result.json + github-token: ${{ secrets.GITHUB_TOKEN }} + + # Enable deployment to GitHub Pages for continuous line graphs + auto-push: true + comment-on-alert: true # Creates a comment if performance degrades + fail-on-alert: true # Fails the workflow run on regression + alert-threshold: '200%' # Triggers an alert if execution time doubles \ No newline at end of file
diff --git a/.gitignore b/.gitignore index 5a92901..1e473a3 100644 --- a/.gitignore +++ b/.gitignore
@@ -15,6 +15,7 @@ .settings/ .classpath .project +bin/ # NetBeans noise nbproject/ @@ -25,3 +26,6 @@ # Java noise *.class *err_pid*.log +dependency-reduced-pom.xml + +.envrc
diff --git a/api/src/main/java/jakarta/json/spi/JsonProvider.java b/api/src/main/java/jakarta/json/spi/JsonProvider.java index 28fe280..b3df62b 100644 --- a/api/src/main/java/jakarta/json/spi/JsonProvider.java +++ b/api/src/main/java/jakarta/json/spi/JsonProvider.java
@@ -23,8 +23,6 @@ import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collection; import java.util.Iterator; import java.util.Map; @@ -108,9 +106,7 @@ */ public static JsonProvider provider() { LOG.log(Level.FINE, "Checking system property {0}", JSONP_PROVIDER_FACTORY); - final String factoryClassName = System.getSecurityManager() != null - ? AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty(JSONP_PROVIDER_FACTORY)) - : System.getProperty(JSONP_PROVIDER_FACTORY); + final String factoryClassName = System.getProperty(JSONP_PROVIDER_FACTORY); if (factoryClassName != null) { JsonProvider provider = newInstance(factoryClassName); LOG.log(Level.FINE, "System property used; returning object [{0}]", @@ -152,7 +148,6 @@ */ private static JsonProvider newInstance(String className) { try { - checkPackageAccess(className); @SuppressWarnings({"unchecked"}) Class<JsonProvider> clazz = (Class<JsonProvider>) Class.forName(className); return clazz.getConstructor().newInstance(); @@ -167,20 +162,6 @@ } /** - * Make sure that the current thread has an access to the package of the given name. - * @param className The class name to check. - */ - private static void checkPackageAccess(String className) { - SecurityManager s = System.getSecurityManager(); - if (s != null) { - int i = className.lastIndexOf('.'); - if (i != -1) { - s.checkPackageAccess(className.substring(0, i)); - } - } - } - - /** * Creates a JSON parser from a character stream. * * @param reader i/o reader from which JSON is to be read
diff --git a/perf/README.md b/perf/README.md new file mode 100644 index 0000000..962cafd --- /dev/null +++ b/perf/README.md
@@ -0,0 +1,30 @@ +# JMH performance tests for Jakarta JSON Processing. + +Binaries for performance testing should never be uploaded into Maven repository. + +## Running tests + - build it with maven + - run from commandline + + +### Build it + +```sh +mvn package -f perf/pom.xml +``` + +### Run it + +For all JMH options available: + +```sh +java -jar perf/target/jsonp-jmh.jar -h +``` + +Run examples: + +```sh +java -jar perf/target/jsonp-jmh.jar +java -jar perf/target/jsonp-jmh.jar -i 3 -t 5 -f 3 -prof stack +java -jar perf/target/jsonp-jmh.jar FactoryBenchmark.createObjectBuilder_viaJson +``` \ No newline at end of file
diff --git a/perf/pom.xml b/perf/pom.xml new file mode 100644 index 0000000..4f2f2b7 --- /dev/null +++ b/perf/pom.xml
@@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.eclipse.ee4j</groupId> + <artifactId>project</artifactId> + <version>2.0.5</version> + </parent> + + <groupId>jakarta.json</groupId> + <artifactId>jakarta.json-perf</artifactId> + <version>2.2.0-SNAPSHOT</version> + + <description>This is a performance testing project for Jakarta JSON-P. + It leverages a JMH technology. + See https://openjdk.java.net/projects/code-tools/jmh/. + </description> + + <properties> + <maven.compiler.release>17</maven.compiler.release> + + <jmh.version>1.37</jmh.version> + <jakarta.json.version>${project.version}</jakarta.json.version> + <maven-shade-plugin.version>3.6.2</maven-shade-plugin.version> + </properties> + + + <dependencies> + <dependency> + <groupId>org.openjdk.jmh</groupId> + <artifactId>jmh-core</artifactId> + <version>${jmh.version}</version> + </dependency> + <dependency> + <groupId>org.openjdk.jmh</groupId> + <artifactId>jmh-generator-annprocess</artifactId> + <version>${jmh.version}</version> + </dependency> + <dependency> + <groupId>jakarta.json</groupId> + <artifactId>jakarta.json-api</artifactId> + <version>${jakarta.json.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <!-- Don't upload any files from these project. JMH dependencies are approved only for testing purposes. --> + <plugin> + <artifactId>maven-deploy-plugin</artifactId> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>${maven-shade-plugin.version}</version> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <finalName>jsonp-jmh</finalName> + <transformers> + <transformer + implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <mainClass>org.openjdk.jmh.Main</mainClass> + </transformer> + </transformers> + <filters> + <filter> + <!-- + Shading signed JARs will fail without this. + http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar + --> + <artifact>*:*</artifact> + <excludes> + <exclude>META-INF/*.SF</exclude> + <exclude>META-INF/*.DSA</exclude> + <exclude>META-INF/*.RSA</exclude> + </excludes> + </filter> + </filters> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project>
diff --git a/perf/src/main/java/jakarta/json/jmh/FactoryBenchmark.java b/perf/src/main/java/jakarta/json/jmh/FactoryBenchmark.java new file mode 100644 index 0000000..e51143a --- /dev/null +++ b/perf/src/main/java/jakarta/json/jmh/FactoryBenchmark.java
@@ -0,0 +1,131 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package jakarta.json.jmh; + +import jakarta.json.Json; +import jakarta.json.JsonBuilderFactory; +import jakarta.json.JsonNumber; +import jakarta.json.JsonString; +import jakarta.json.spi.JsonProvider; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.concurrent.TimeUnit; + +/** + * Benchmarks for issue #154 — "Json factory methods are very inefficient". + * + * <p>Each {@code Json.*} convenience method calls {@link JsonProvider#provider()} + * on every invocation, which triggers a ServiceLoader scan and is orders of + * magnitude slower than caching the provider or using a factory. + * + * <p>Three strategies are compared for each operation: + * <ol> + * <li><b>viaJson</b> – {@link Json} helper (slow path, provider lookup per call)</li> + * <li><b>viaFactory</b> – cached {@link JsonBuilderFactory} (recommended workaround for builders)</li> + * <li><b>viaProvider</b> – cached static {@link JsonProvider} (recommended workaround for createValue)</li> + * </ol> + * + * @see <a href="https://github.com/jakartaee/jsonp-api/issues/154">jakartaee/jsonp-api#154</a> + */ +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +@Warmup(iterations = 3, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(1) +public class FactoryBenchmark { + + // --- cached instances (the recommended workarounds from issue #154) --- + + private static final JsonProvider PROVIDER = JsonProvider.provider(); + + private static final JsonBuilderFactory BUILDER_FACTORY = Json.createBuilderFactory(null); + + // ----------------------------------------------------------------------- + // createObjectBuilder + // ----------------------------------------------------------------------- + + @Benchmark + public void createObjectBuilder_viaJson(Blackhole bh) { + bh.consume(Json.createObjectBuilder()); + } + + @Benchmark + public void createObjectBuilder_viaFactory(Blackhole bh) { + bh.consume(BUILDER_FACTORY.createObjectBuilder()); + } + + @Benchmark + public void createObjectBuilder_viaProvider(Blackhole bh) { + bh.consume(PROVIDER.createObjectBuilder()); + } + + // ----------------------------------------------------------------------- + // createArrayBuilder + // ----------------------------------------------------------------------- + + @Benchmark + public void createArrayBuilder_viaJson(Blackhole bh) { + bh.consume(Json.createArrayBuilder()); + } + + @Benchmark + public void createArrayBuilder_viaFactory(Blackhole bh) { + bh.consume(BUILDER_FACTORY.createArrayBuilder()); + } + + @Benchmark + public void createArrayBuilder_viaProvider(Blackhole bh) { + bh.consume(PROVIDER.createArrayBuilder()); + } + + // ----------------------------------------------------------------------- + // createValue (String) — no JsonBuilderFactory equivalent + // ----------------------------------------------------------------------- + + @Benchmark + public void createValueString_viaJson(Blackhole bh) { + bh.consume(Json.createValue("test")); + } + + @Benchmark + public void createValueString_viaProvider(Blackhole bh) { + bh.consume(PROVIDER.createValue("test")); + } + + // ----------------------------------------------------------------------- + // createValue (int) — no JsonBuilderFactory equivalent + // ----------------------------------------------------------------------- + + @Benchmark + public void createValueInt_viaJson(Blackhole bh) { + bh.consume(Json.createValue(42)); + } + + @Benchmark + public void createValueInt_viaProvider(Blackhole bh) { + bh.consume(PROVIDER.createValue(42)); + } +}
diff --git a/perf/src/main/java/jakarta/json/jmh/provider/NoopJsonProvider.java b/perf/src/main/java/jakarta/json/jmh/provider/NoopJsonProvider.java new file mode 100644 index 0000000..c0d922c --- /dev/null +++ b/perf/src/main/java/jakarta/json/jmh/provider/NoopJsonProvider.java
@@ -0,0 +1,218 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package jakarta.json.jmh.provider; + +import jakarta.json.JsonArray; +import jakarta.json.JsonArrayBuilder; +import jakarta.json.JsonBuilderFactory; +import jakarta.json.JsonNumber; +import jakarta.json.JsonObject; +import jakarta.json.JsonObjectBuilder; +import jakarta.json.JsonString; +import jakarta.json.JsonValue; +import jakarta.json.spi.JsonProvider; +import jakarta.json.stream.JsonGenerator; +import jakarta.json.stream.JsonGeneratorFactory; +import jakarta.json.stream.JsonParser; +import jakarta.json.stream.JsonParserFactory; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Map; + +/** + * Minimal {@link JsonProvider} implementation used only for JMH benchmarks. + * + * <p>Methods required by the benchmarks in {@link FactoryTest} are fully + * implemented with lightweight no-op objects so the benchmark measures + * provider-lookup and dispatch overhead rather than real JSON construction. + * Every other abstract method throws {@link UnsupportedOperationException}. + * + * <p>Registered via {@code META-INF/services/jakarta.json.spi.JsonProvider} + * so that {@link jakarta.json.spi.JsonProvider#provider()} resolves to this + * class through the ServiceLoader without requiring a real implementation on + * the classpath. + */ +public class NoopJsonProvider extends JsonProvider { + + // ----------------------------------------------------------------------- + // Builders + // ----------------------------------------------------------------------- + + @Override + public JsonObjectBuilder createObjectBuilder() { + return new NoopObjectBuilder(); + } + + @Override + public JsonArrayBuilder createArrayBuilder() { + return new NoopArrayBuilder(); + } + + @Override + public JsonBuilderFactory createBuilderFactory(Map<String, ?> config) { + return NoopBuilderFactory.INSTANCE; + } + + // ----------------------------------------------------------------------- + // createValue + // ----------------------------------------------------------------------- + + @Override + public JsonString createValue(String value) { + return new NoopJsonString(); + } + + @Override + public JsonNumber createValue(int value) { + return new NoopJsonNumber(); + } + + // ----------------------------------------------------------------------- + // Remaining abstract methods — not exercised by the benchmarks + // ----------------------------------------------------------------------- + + @Override + public JsonParser createParser(Reader reader) { + throw new UnsupportedOperationException(); + } + + @Override + public JsonParser createParser(InputStream in) { + throw new UnsupportedOperationException(); + } + + @Override + public JsonParserFactory createParserFactory(Map<String, ?> config) { + throw new UnsupportedOperationException(); + } + + @Override + public JsonGenerator createGenerator(Writer writer) { + throw new UnsupportedOperationException(); + } + + @Override + public JsonGenerator createGenerator(OutputStream out) { + throw new UnsupportedOperationException(); + } + + @Override + public JsonGeneratorFactory createGeneratorFactory(Map<String, ?> config) { + throw new UnsupportedOperationException(); + } + + @Override + public jakarta.json.JsonReader createReader(Reader reader) { + throw new UnsupportedOperationException(); + } + + @Override + public jakarta.json.JsonReader createReader(InputStream in) { + throw new UnsupportedOperationException(); + } + + @Override + public jakarta.json.JsonWriter createWriter(Writer writer) { + throw new UnsupportedOperationException(); + } + + @Override + public jakarta.json.JsonWriter createWriter(OutputStream out) { + throw new UnsupportedOperationException(); + } + + @Override + public jakarta.json.JsonWriterFactory createWriterFactory(Map<String, ?> config) { + throw new UnsupportedOperationException(); + } + + @Override + public jakarta.json.JsonReaderFactory createReaderFactory(Map<String, ?> config) { + throw new UnsupportedOperationException(); + } + + // ----------------------------------------------------------------------- + // No-op inner types + // ----------------------------------------------------------------------- + + /** No-op {@link JsonObjectBuilder}. */ + private static final class NoopObjectBuilder implements JsonObjectBuilder { + @Override public JsonObjectBuilder add(String name, JsonValue value) { return this; } + @Override public JsonObjectBuilder add(String name, String value) { return this; } + @Override public JsonObjectBuilder add(String name, BigInteger value) { return this; } + @Override public JsonObjectBuilder add(String name, BigDecimal value) { return this; } + @Override public JsonObjectBuilder add(String name, int value) { return this; } + @Override public JsonObjectBuilder add(String name, long value) { return this; } + @Override public JsonObjectBuilder add(String name, double value) { return this; } + @Override public JsonObjectBuilder add(String name, boolean value) { return this; } + @Override public JsonObjectBuilder addNull(String name) { return this; } + @Override public JsonObjectBuilder add(String name, JsonObjectBuilder builder) { return this; } + @Override public JsonObjectBuilder add(String name, JsonArrayBuilder builder) { return this; } + @Override public JsonObject build() { return JsonValue.EMPTY_JSON_OBJECT; } + } + + /** No-op {@link JsonArrayBuilder}. */ + private static final class NoopArrayBuilder implements JsonArrayBuilder { + @Override public JsonArrayBuilder add(JsonValue value) { return this; } + @Override public JsonArrayBuilder add(String value) { return this; } + @Override public JsonArrayBuilder add(BigInteger value) { return this; } + @Override public JsonArrayBuilder add(BigDecimal value) { return this; } + @Override public JsonArrayBuilder add(int value) { return this; } + @Override public JsonArrayBuilder add(long value) { return this; } + @Override public JsonArrayBuilder add(double value) { return this; } + @Override public JsonArrayBuilder add(boolean value) { return this; } + @Override public JsonArrayBuilder addNull() { return this; } + @Override public JsonArrayBuilder add(JsonObjectBuilder builder) { return this; } + @Override public JsonArrayBuilder add(JsonArrayBuilder builder) { return this; } + @Override public JsonArray build() { return JsonValue.EMPTY_JSON_ARRAY; } + } + + /** Singleton no-op {@link JsonBuilderFactory}. */ + private static final class NoopBuilderFactory implements JsonBuilderFactory { + static final NoopBuilderFactory INSTANCE = new NoopBuilderFactory(); + + @Override public JsonObjectBuilder createObjectBuilder() { return new NoopObjectBuilder(); } + @Override public JsonArrayBuilder createArrayBuilder() { return new NoopArrayBuilder(); } + @Override public Map<String, ?> getConfigInUse() { return Map.of(); } + } + + /** Singleton no-op {@link JsonString}. */ + private static final class NoopJsonString implements JsonString { + @Override public String getString() { return ""; } + @Override public CharSequence getChars() { return ""; } + @Override public ValueType getValueType() { return ValueType.STRING; } + } + + /** Singleton no-op {@link JsonNumber}. */ + private static final class NoopJsonNumber implements JsonNumber { + @Override public boolean isIntegral() { return true; } + @Override public int intValue() { return 0; } + @Override public int intValueExact() { return 0; } + @Override public long longValue() { return 0L; } + @Override public long longValueExact() { return 0L; } + @Override public BigInteger bigIntegerValue() { return BigInteger.ZERO; } + @Override public BigInteger bigIntegerValueExact() { return BigInteger.ZERO; } + @Override public double doubleValue() { return 0.0; } + @Override public BigDecimal bigDecimalValue() { return BigDecimal.ZERO; } + @Override public ValueType getValueType() { return ValueType.NUMBER; } + @Override public String toString() { return "0"; } + } +}
diff --git a/perf/src/main/resources/META-INF/services/jakarta.json.spi.JsonProvider b/perf/src/main/resources/META-INF/services/jakarta.json.spi.JsonProvider new file mode 100644 index 0000000..ff25ce1 --- /dev/null +++ b/perf/src/main/resources/META-INF/services/jakarta.json.spi.JsonProvider
@@ -0,0 +1 @@ +jakarta.json.jmh.provider.NoopJsonProvider
diff --git a/spec/src/main/asciidoc/jsonp-spec.adoc b/spec/src/main/asciidoc/jsonp-spec.adoc index 5077a92..b06f445 100644 --- a/spec/src/main/asciidoc/jsonp-spec.adoc +++ b/spec/src/main/asciidoc/jsonp-spec.adoc
@@ -1,5 +1,5 @@ // -// Copyright (c) 2017, 2020 Contributors to the Eclipse Foundation +// Copyright (c) 2017, 2026 Contributors to the Eclipse Foundation // = Jakarta JSON Processing @@ -7,7 +7,7 @@ :email: https://dev.eclipse.org/mailman/listinfo/jsonp-dev :version-label!: :doctype: book -:license: Eclipse Foundation Specification License v1.0 +:license: Eclipse Foundation Specification License v2.0 :source-highlighter: coderay :toc: left :toclevels: 4
diff --git a/spec/src/main/asciidoc/license-efsl.adoc b/spec/src/main/asciidoc/license-efsl.adoc index d900a4a..b5e1385 100644 --- a/spec/src/main/asciidoc/license-efsl.adoc +++ b/spec/src/main/asciidoc/license-efsl.adoc
@@ -14,66 +14,30 @@ Release: {revdate} .... -Copyright (c) 2019 Eclipse Foundation. +Copyright (c) 2019, 2026 Contributors to the Eclipse Foundation -=== Eclipse Foundation Specification License +== Eclipse Foundation Specification License - v2.0 -By using and/or copying this document, or the Eclipse Foundation -document from which this statement is linked, you (the licensee) agree -that you have read, understood, and will comply with the following -terms and conditions: +This license (the "`License`") governs the use, modification and distribution of a specification generated pursuant to the Eclipse Foundation Specification Process. -Permission to copy, and distribute the contents of this document, or -the Eclipse Foundation document from which this statement is linked, in -any medium for any purpose and without fee or royalty is hereby -granted, provided that you include the following on ALL copies of the -document, or portions thereof, that you use: +By using the file or document that incorporates this License (the "`Document`"), you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions. -* link or URL to the original Eclipse Foundation document. -* All existing copyright notices, or if one does not exist, a notice - (hypertext is preferred, but a textual representation is permitted) - of the form: "Copyright (c) [$date-of-document] - Eclipse Foundation, Inc. <<url to this license>>" +Permission to copy and distribute the contents of the Document, in any medium for any purpose, and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the Document that you copy or distribute: -Inclusion of the full text of this NOTICE must be provided. We -request that authorship attribution be provided in any software, -documents, or other items or products that you create pursuant to the -implementation of the contents of this document, or any portion -thereof. +- link or URL to the Document +- All existing copyright notices, or if one does not exist, a notice (hypertext is preferred, but a textual representation is permitted) of the form: "`Copyright (C) [date-of-document] Eclipse Foundation AISBL [URL to this license] This document includes material copied from [title and URL of the Eclipse Foundation specification document].`" -No right to create modifications or derivatives of Eclipse Foundation -documents is granted pursuant to this license, except anyone may -prepare and distribute derivative works and portions of this document -in software that implements the specification, in supporting materials -accompanying such software, and in documentation of such software, -PROVIDED that all such works include the notice below. HOWEVER, the -publication of derivative works of this document for use as a technical -specification is expressly prohibited. +In addition to the license granted above, you are granted the right to create modifications or derivatives of the Document: -The notice is: +- in software that implements the Document, in supporting materials accompanying such software, and in documentation of such software (collectively the "`Works`"), such Works to be made available under terms of your choice PROVIDED that all such Works include a notice of the form: "`This [software/document (choose as applicable)] includes material derived from [title and URL of the Eclipse Foundation specification document].`"; and +- in materials that demonstrate or describe conformance with the Document PROVIDED that all such materials include a notice of the form: "`This material demonstrates conformance with the [title and URL of the Eclipse Foundation specification document].`" -"Copyright (c) 2018 Eclipse Foundation. This software or -document includes material copied from or derived from [title and URI -of the Eclipse Foundation specification document]." +NOTWITHSTANDING THE FOREGOING, the creation or publication of derivative works of the Document or portions of the Document for use as a specification or standard is expressly prohibited. -==== Disclaimers +=== Disclaimers -THIS DOCUMENT IS PROVIDED "AS IS," AND THE COPYRIGHT -HOLDERS AND THE ECLIPSE FOUNDATION MAKE NO REPRESENTATIONS OR -WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, -NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE -SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS -WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR -OTHER RIGHTS. +THE DOCUMENT IS PROVIDED "AS IS," AND TO THE EXTENT PERMITTED BY APPLICABLE LAW THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION AISBL MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. -THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION WILL NOT BE LIABLE -FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT -OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE -CONTENTS THEREOF. +TO THE EXTENT PERMITTED BY APPLICABLE LAW THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION AISBL WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF. -The name and trademarks of the copyright holders or the Eclipse -Foundation may NOT be used in advertising or publicity pertaining to -this document or its contents without specific, written prior -permission. Title to copyright in this document will at all times -remain with copyright holders. \ No newline at end of file +The name and trademarks of the copyright holders or the Eclipse Foundation AISBL may NOT be used in advertising or publicity pertaining to this document or its contents without specific, written prior permission.