This is an automated email from the ASF dual-hosted git repository.
slawrence pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil-site.git
The following commit(s) were added to refs/heads/main by this push:
new 0ac1ca1 Add Migration Guide for 3.11.0 to 4.0.0
0ac1ca1 is described below
commit 0ac1ca156c1055ef3ead5df55bf77c503675c815
Author: olabusayoT <[email protected]>
AuthorDate: Tue Jun 24 12:46:30 2025 -0400
Add Migration Guide for 3.11.0 to 4.0.0
DAFFODIL-2975
---
README.md | 2 +-
site/migration-guides.md | 59 +++++
site/migration-guides/4.0.0.md | 512 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 572 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 6f9a457..4489404 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,7 @@ served by the Jekyll container. Changes to files in the site
directory are
automatically rebuilt and served.
Once satisfied, create a branch and open a pull request using the Daffodil
-project [Code Conttributor
Workflow](https://cwiki.apache.org/confluence/display/DAFFODIL/Code+Contributor+Workflow)
+project [Code Contributor
Workflow](https://cwiki.apache.org/confluence/display/DAFFODIL/Code+Contributor+Workflow)
but using the website repo instead of the code repo.
## Publishing to the Live Site
diff --git a/site/migration-guides.md b/site/migration-guides.md
new file mode 100644
index 0000000..e3fe045
--- /dev/null
+++ b/site/migration-guides.md
@@ -0,0 +1,59 @@
+---
+layout: page
+title: Migration Guides
+group: nav-right
+---
+<!--
+{% comment %}
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to you under the Apache License, Version 2.0
+(the "License"); 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
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+-->
+### Migration Guides
+
+{% assign guides = site.pages
+| where_exp: "p", "p.path contains 'migration-guides/'"
+| sort: "date" %}
+
+{% if guides.size > 0 %}
+<table class="table">
+ <tr>
+ <th class="col-md-1">Version</th>
+ <th>Summary</th>
+ <th class="col-md-2 text-right">Date</th>
+ </tr>
+ {% for p in guides reversed %}
+ {% assign version = p.version | default: p.title | replace: "Migration
Guide",""
+ | default: p.url | split: "/" | last | replace: ".html","" %}
+ {% assign date_val = p.date | default: p.last_modified_at %}
+ {% assign summary = p.summary | default: p.excerpt | default: "" %}
+ <tr>
+ <td style="vertical-align: middle; line-height: 2.5em;" class="col-md-1">
+ <a href="{{ p.url | prepend: site.baseurl }}">{{ version }}</a>
+ </td>
+ <td style="vertical-align: middle;">
+ {{ summary }}
+ </td>
+ <td style="vertical-align: middle;" class="col-md-2 text-right">
+ {% if date_val %}{{ date_val | date: "%Y-%m-%d" }}{% else %}—{%
endif %}
+ </td>
+ </tr>
+ {% endfor %}
+</table>
+{% else %}
+<div class="alert alert-warning">
+No migration guides found yet. Add files under <code>migration-guides/</code>
like <code>4.0.0.md</code>.
+</div>
+{% endif %}
diff --git a/site/migration-guides/4.0.0.md b/site/migration-guides/4.0.0.md
new file mode 100644
index 0000000..3ef3908
--- /dev/null
+++ b/site/migration-guides/4.0.0.md
@@ -0,0 +1,512 @@
+---
+layout: page
+title: 4.0.0 Migration Guide
+date: 2025-09-01
+summary: >
+ Upgrade from 3.x to 4.0.0
+group: nav-right
+---
+
+<!--
+{% comment %}
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to you under the Apache License, Version 2.0
+(the "License"); 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
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+-->
+
+<div class="well">
+ <div class="row">
+ <div class="col-sm-9">
+ This migration guide provides examples in both Java and Scala. Use the
buttons on the right to select your preferred language.
+ </div>
+ <div class="col-sm-3 text-right">
+ <div id="lang-toggle" class="btn-group" data-toggle="buttons">
+ <label class="btn btn-primary active">
+ <input type="radio" name="lang" id="lang-java" autocomplete="off"
checked> Java
+ </label>
+ <label class="btn btn-primary">
+ <input type="radio" name="lang" id="lang-scala" autocomplete="off">
Scala
+ </label>
+ </div>
+ </div>
+ </div>
+</div>
+
+### 3.11.0 to 4.0.0
+
+Overview of changes to be aware of in this release are:
+
+- Daffodil now requires Scala 3.3.6 and Java 17+
+- Daffodil has merged daffodil-udf, daffodil-runtime1,
daffodil-runtime1-unparser, daffodil-lib,
+ daffodil-sapi, daffodil-japi and daffodil-io into daffodil-core.
+- Daffodil has replaced the Validation
Modes(`withValidationMode`)/`withValidator` with the
`withValidation(validatorName[, validationConfigurationURL])` method. Built-in
validator names are xerces, daffodil, schematron and off.
+- com.typesafe.config class has been replaced with java.util.Properties class
for Validators configuration
+- getDiagnostics returns a java.util.List instead of a Seq
+- Diagnostic removed getSomeMessage and getSomeCause
+- withExternalVariables expects a Java Map instead of Scala Map.
+- Diagnostic.getMessage() now returns just the message, and toString should be
used if the diagnostic context is needed
+- getAnyRef in MetaData has been removed
+
+#### Dependencies
+
+The following dependencies have been merged into daffodil-core:
+
+- daffodil-udf
+- daffodil-sapi
+- daffodil-japi
+- daffodil-runtime1
+- daffodil-runtime1-unparser
+- daffodil-lib
+- daffodil-io
+
+Dependencies to the listed jars should be changed to the following.
+
+```xml
+<dependency>
+ <groupId>org.apache.daffodil</groupId>
+ <artifactId>daffodil-core_3</artifactId>
+ <version>4.0.0</version>
+</dependency>
+```
+
+```scala
+scalaVersion := "3.3.6"
+libraryDependencies += "org.apache.daffodil" %% "daffodil-core" % "4.0.0"
+```
+#### Core Imports
+The path to core api classes were updated from `japi`/`sapi` to `api`
+
+```java
+// ----- BEFORE -----
+import org.apache.daffodil.japi.ProcessorFactory;
+import org.apache.daffodil.japi.Daffodil; // factory method for compiler
+import org.apache.daffodil.japi.DataProcessor;
+import org.apache.daffodil.japi.Diagnostic;
+import org.apache.daffodil.japi.ParseResult;
+import org.apache.daffodil.japi.UnparseResult;
+import org.apache.daffodil.japi.DaffodilParseXMLReader;
+import org.apache.daffodil.japi.DaffodilUnparseContentHandler;
+import org.apache.daffodil.japi.io.InputSourceDataInputStream;
+import org.apache.daffodil.japi.infoset.*; // all InfosetInputters and
InfosetOutputters
+
+// ----- AFTER -----
+import org.apache.daffodil.api.ProcessorFactory;
+import org.apache.daffodil.api.Daffodil; // factory method for compiler,
InfosetInputter/Outputters and many others
+import org.apache.daffodil.api.DataProcessor;
+import org.apache.daffodil.api.Diagnostic;
+import org.apache.daffodil.api.ParseResult;
+import org.apache.daffodil.api.UnparseResult;
+import org.apache.daffodil.api.DaffodilParseXMLReader;
+import org.apache.daffodil.api.DaffodilUnparseContentHandler;
+import org.apache.daffodil.api.InputSourceDataInputStream;
+import org.apache.daffodil.api.infoset.*; // InfosetInputter,
InfosetOutputter, JDOM/Scala/W3CDOM InfosetOutputters
+```
+
+```scala
+// ----- BEFORE -----
+import org.apache.daffodil.sapi.ProcessorFactory
+import org.apache.daffodil.sapi.Daffodil // factory method for compiler
+import org.apache.daffodil.sapi.DataProcessor
+import org.apache.daffodil.sapi.Diagnostic
+import org.apache.daffodil.sapi.ParseResult
+import org.apache.daffodil.sapi.UnparseResult
+import org.apache.daffodil.sapi.DaffodilParseXMLReader
+import org.apache.daffodil.sapi.DaffodilUnparseContentHandler
+import org.apache.daffodil.sapi.io.InputSourceDataInputStream
+import org.apache.daffodil.sapi.infoset._ // all InfosetInputters and
InfosetOutputters
+
+// ----- AFTER -----
+import org.apache.daffodil.api.ProcessorFactory
+import org.apache.daffodil.api.Daffodil // factory method for compiler,
InfosetInputter/Outputters and many others
+import org.apache.daffodil.api.DataProcessor
+import org.apache.daffodil.api.Diagnostic
+import org.apache.daffodil.api.ParseResult
+import org.apache.daffodil.api.UnparseResult
+import org.apache.daffodil.api.DaffodilParseXMLReader
+import org.apache.daffodil.api.DaffodilUnparseContentHandler
+import org.apache.daffodil.api.InputSourceDataInputStream
+import org.apache.daffodil.api.infoset.* // InfosetInputter, InfosetOutputter,
JDOM/Scala/W3CDOM InfosetOutputters
+
+```
+
+#### CLI Validation
+Values for the `--validate` option have been renamed: `on` has been replaced
with `xerces` and `limited` has been replaced with `daffodil`.
+Both `schematron` and `xerces` accept option values that provide a file
+to the validator for validator configuration. If no value is provided, it will
attempt to use the schema provided by `--schema`.
+The file can either be a .xsd, .sch, .conf or .properties file. Typesafe
configs have been replaced with java.util.Properties.
+`--validate {schematron|xerces}=value` can be used with `--parser`, enabling
+Xerces/Schematron validation with a saved parser.
+
+```bash
+# ----- BEFORE -----
+daffodil parse --validate on -s schema.xsd input.dat
+daffodil parse --validate limited --parser schema.parser myData.dat
+daffodil parse --validate on --parser schema.parser myData.dat # would lead to
error
+daffodil parse --validate schematron=schema.sch --parser schema.parser
myData.dat # would lead to error
+
+# ----- AFTER -----
+daffodil parse --validate xerces -s schema.xsd input.dat
+daffodil parse --validate daffodil --parser schema.parser myData.dat
+daffiduk parse --validate xerces=schema.xsd --parser schema.parser myData.dat
# no error and validates
+daffiduk parse --validate schematron=schema.sch --parser schema.parser
myData.dat # no error and validates
+```
+
+#### Compiling Schemas
+This remains generally unchanged for Java users as passing in strings (or
nulls) is still supported. For Scala users, Options are no longer supported in
the api and strings (or nulls) must be passed in instead.
+
+```java
+// unchanged save for import paths
+```
+
+```scala
+// ----- BEFORE -----
+val pf: ProcessorFactory = c.compileFile(schemaFile, None, None)
+
+// ----- AFTER -----
+val pf: ProcessorFactory = c.compileFile(schemaFile, null, null)
+// or
+val pf = c.compileFile(schemaFile)
+```
+
+#### DataProcessor Validation
+Validation Modes (i.e `withValidationMode(ValidationMode.*)`) and the
`withValidator(validatorObj)` were removed in place of
`withValidation(validator.name[, validationConfigurationURL])`. Some validators
have mandatory properties--if not provided an exception will be thrown. See the
[validator
documentation](/docs/4.0.0/javadoc/org/apache/daffodil/api/validation/package-summary.html)
for the list of those properties.
+ Custom validators must be found via SPI and are not expected to be directly
created.
+
+```java
+// ----- BEFORE -----
+DataProcessor dp = pf.onPath("/").withValidationMode(ValidationMode.Full);
+// or
+DataProcessor dp = pf.onPath("/").withValidator(new CustomValidator());
+
+// ----- AFTER -----
+DataProcessor dp = pf.onPath("/").withValidation("xerces", schemaUrl);
+//or
+DataProcessor dp = pf.onPath("/").withValidation("CUSTOM-VALIDATOR-NAME",
schemaUrl);
+```
+
+```scala
+// ----- BEFORE -----
+val dp: DataProcessor = pf.onPath("/").withValidationMode(ValidationMode.Full)
+// or
+val dp: DataProcessor = pf.onPath("/").withValidator(new CustomValidator())
+
+// ----- AFTER -----
+val dp: DataProcessor = pf.onPath("/").withValidation("xerces", schemaUrl)
+//or
+val dp: DataProcessor = pf.onPath("/").withValidation("CUSTOM-VALIDATOR-NAME",
schemaUrl)
+```
+
+#### Parse
+Factory methods to get `InputSourceDataInputStream` and `InfosetOutputter`
objects have been added via
+`Daffodil.newInputSourceDataInputStream` and `Infoset.new*InfosetOutputter`
+
+```java
+// ----- BEFORE -----
+InputSourceDataInputStream dis = new InputSourceDataInputStream(fis);
+JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+XMLTextInfosetOutputter outputter = new XMLTextInfosetOutputter();
+JsonInfosetOutputter outputter = new JsonInfosetOutputter();
+
+// ----- AFTER -----
+InputSourceDataInputStream dis = Daffodil.newInputSourceDataInputStream(fis);
+JDOMInfosetOutputter outputter = Daffodil.newJDOMInfosetOutputter();
+InfosetOutputter outputter = Daffodil.newXMLTextInfosetOutputter();
+InfosetOutputter outputter = Daffodil.newJsonInfosetOutputter();
+```
+
+```scala
+// ----- BEFORE -----
+val dis = new InputSourceDataInputStream(fis)
+val outputter = new ScalaXMLInfosetOutputter()
+val outputter = new XMLTextInfosetOutputter()
+val outputter = new JsonInfosetOutputter()
+
+// ----- AFTER -----
+val dis = Daffodil.newInputSourceDataInputStream(fis)
+val outputter = Daffodil.newScalaXMLInfosetOutputter()
+val outputter = Daffodil.newXMLTextInfosetOutputter()
+val outputter = Daffodil.newJsonInfosetOutputter()
+```
+
+#### Unparse
+Factory methods to get an `InfosetInputter` object has been added via
`Daffodil.new*InfosetInputter`
+
+```java
+// ----- BEFORE -----
+JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
+
+// ----- AFTER -----
+InfosetInputter inputter =
Daffodil.newJDOMInfosetInputter(outputter.getResult());
+```
+
+```scala
+// ----- BEFORE -----
+val inputter = new ScalaXMLInfosetInputter(outputter.getResult())
+
+// ----- AFTER -----
+val inputter = Daffodil.newScalaXMLInfosetInputter(outputter.getResult())
+```
+
+#### Debuggers
+The different ways debuggers are defined and enabled have changed.
+Factory methods to get a `Debugger` object have been added via
`Daffodil.newDaffodilDebugger`.
+
+Using a custom debugger:
+```java
+// ----- BEFORE -----
+import org.apache.daffodil.japi.debugger.Debugger;
+
+final class CustomDebugger extends Debugger {
+ // implementation details
+}
+
+// to use
+dp = dp.withDebugger(new CustomDebugger());
+dp = dp.withDebugging(true);
+
+// ----- AFTER -----
+import org.apache.daffodil.api.debugger.Debugger;
+
+final class CustomDebugger extends Debugger {
+ // implementation details
+}
+dp.withDebugger(new CustomDebugger())
+```
+```scala
+// ----- BEFORE -----
+import org.apache.daffodil.sapi.debugger.Debugger
+
+class CustomDebugger extends Debugger { ... }
+// to use
+dp.withDebugger(new CustomDebugger())
+
+// ----- AFTER -----
+import org.apache.daffodil.api.debugger.Debugger
+
+class CustomDebugger extends Debugger { ... }
+// to use
+dp.withDebugger(new CustomDebugger())
+```
+
+Using a custom debugger runner:
+```java
+// ----- BEFORE -----
+import org.apache.daffodil.japi.debugger.DebuggerRunner;
+
+final class CustomDebuggerRunner extends DebuggerRunner {
+ // implementation details
+}
+
+// to use
+import org.apache.daffodil.japi.Debugger;
+
+Debugger debugger = new CustomDebuggerRunner();
+dp = dp.withDebuggerRunner(debugger);
+dp = dp.withDebugging(true);
+
+// ----- AFTER -----
+import org.apache.daffodil.api.debugger.DaffodilDebuggerRunner;
+
+final class CustomDebuggerRunner extends DaffodilDebuggerRunner {
+ // implementation details
+}
+
+// to use
+import org.apache.daffodil.api.debugger.Debugger;
+
+Debugger debugger = Daffodil.newDaffodilDebugger(new CustomDebuggerRunner());
+dp.withDebugger(debugger);
+```
+
+```scala
+// ----- BEFORE -----
+import org.apache.daffodil.sapi.debugger.DebuggerRunner
+
+final class CustomDebuggerRunner extends DebuggerRunner {...}
+
+// to use
+import org.apache.daffodil.sapi.debugger.Debugger
+
+dp.withDebuggerRunner(new CustomDebuggerRunner())
+ .withDebugging(true)
+
+// ----- AFTER -----
+import org.apache.daffodil.api.debugger.DaffodilDebuggerRunner
+
+final class CustomDebuggerRunner extends DaffodilDebuggerRunner {...}
+
+// to use
+import org.apache.daffodil.api.debugger.Debugger
+import org.apache.daffodil.api.Daffodil
+
+val debugger = Daffodil.newDaffodilDebugger(new CustomDebuggerRunner())
+dp.withDebugger(debugger)
+```
+
+Using the built-in trace debugger:
+```java
+// ----- BEFORE -----
+import org.apache.daffodil.japi.debugger.TraceDebuggerRunner;
+
+dp = dp.withDebuggerRunner(new TraceDebuggerRunner());
+dp = dp.withDebugging(true);
+
+// ----- AFTER -----
+import org.apache.daffodil.api.debugger.Debugger;
+
+Debugger traceDebugger = Daffodil.newTraceDebugger(System.out);
+dp.withDebugger(traceDebugger);
+```
+
+```scala
+// ----- BEFORE -----
+import org.apache.daffodil.sapi.debugger.TraceDebuggerRunner
+
+dp.withDebuggerRunner(new TraceDebuggerRunner())
+ .withDebugging(true)
+
+// ----- AFTER -----
+val traceDebugger = Daffodil.newTraceDebugger(System.out)
+dp.withDebugger(traceDebugger)
+```
+
+#### Layers
+Custom Plug-in layers must extend the `org.apache.daffodil.api.layers.Layer`
class, and be
+referenced in a `META-INF/services` file with the same class reference as the
name. This
+path has changed in Daffodil 4.0.0.
+
+```java
+// ----- BEFORE -----
+// example layer class
+package com.example.layers;
+
+import org.apache.daffodil.runtime1.layers.api.Layer;
+
+public final class CustomLayer extends Layer {
+// implementation details
+}
+
+// in META-INF/services/org.apache.daffodil.runtime1.layers.api.Layer
+com.example.layers.CustomLayer
+
+// ----- AFTER -----
+// example layer class
+package com.example.layers;
+
+import org.apache.daffodil.api.layers.Layer;
+
+public final class CustomLayer extends Layer {
+ // implementation details
+}
+
+// in META-INF/services/org.apache.daffodil.api.layers.Layer
+com.example.layers.CustomLayer
+```
+
+```scala
+// ----- BEFORE -----
+// example layer class
+package com.example.layers
+
+import org.apache.daffodil.runtime1.layers.api.Layer
+
+final class CustomLayer extends Layer("customLayer",
"com.example.layers.customLayer") {...}
+
+// in META-INF/services/org.apache.daffodil.runtime1.layers.api.Layer
+com.example.layers.CustomLayer
+
+// ----- AFTER -----
+// example layer class
+package com.example.layers
+
+import org.apache.daffodil.api.layers.Layer
+
+final class CustomLayer extends Layer("customLayer",
"com.example.layers.customLayer") {...}
+
+// in META-INF/services/org.apache.daffodil.api.layers.Layer
+com.example.layers.CustomLayer
+```
+
+#### User Defined Functions
+UDF Providers must extend the
`org.apache.daffodil.api.udf.UserDefinedFunctionProvider` class, and be
+referenced in a `META-INF/services` file with the same class reference as the
name. This
+path has changed in Daffodil 4.0.0.
+
+
+```java
+// ----- BEFORE -----
+// example UDF Provider class
+package com.example.udf;
+
+import org.apache.daffodil.udf.UserDefinedFunctionProvider;
+
+public class CustomUDFProvider extends UserDefinedFunctionProvider {
+ // implementation details
+}
+
+// in META-INF/services/org.apache.daffodil.udf.UserDefinedFunctionProvider
+com.example.udf.CustomUDFProvider
+
+// ----- AFTER -----
+// example UDF Provider class
+package com.example.udf;
+
+import org.apache.daffodil.api.udf.UserDefinedFunctionProvider;
+
+public class CustomUDFProvider extends UserDefinedFunctionProvider {
+ // implementation details
+}
+
+// in META-INF/services/org.apache.daffodil.api.udf.UserDefinedFunctionProvider
+com.example.udf.CustomUDFProvider
+```
+
+```scala
+// ----- BEFORE -----
+// example UDF Provider class
+package com.example.udf
+
+import org.apache.daffodil.udf.UserDefinedFunctionProvider
+
+class CustomUDFProvider extends UserDefinedFunctionProvider {...}
+
+// in META-INF/services/org.apache.daffodil.udf.UserDefinedFunctionProvider
+com.example.udf.CustomUDFProvider
+
+// ----- AFTER -----
+// example UDF Provider class
+package com.example.udf
+
+import org.apache.daffodil.api.udf.UserDefinedFunctionProvider
+
+class CustomUDFProvider extends UserDefinedFunctionProvider {...}
+
+// in META-INF/services/org.apache.daffodil.api.udf.UserDefinedFunctionProvider
+com.example.udf.CustomUDFProvider
+```
+
+<script>
+ function updateExamples() {
+ const activeBtn = document.querySelector('#lang-toggle .btn.active input');
+ const showJava = activeBtn && activeBtn.id === 'lang-java';
+ document.querySelectorAll('.language-xml').forEach(el =>
el.classList.toggle('hidden', !showJava));
+ document.querySelectorAll('.language-java').forEach(el =>
el.classList.toggle('hidden', !showJava));
+ document.querySelectorAll('.language-scala').forEach(el =>
el.classList.toggle('hidden', showJava));
+ }
+ document.querySelectorAll('#lang-toggle .btn').forEach(btn => {
+ btn.addEventListener('click', () => setTimeout(updateExamples, 0));
+ });
+ updateExamples();
+</script>