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-sbt.git


The following commit(s) were added to refs/heads/main by this push:
     new d9123b4  Require Scala 2.13.16 when for Daffodil 3.11.0
d9123b4 is described below

commit d9123b4804600ba164e8b5bce8b7d5108a59e25d
Author: Steve Lawrence <[email protected]>
AuthorDate: Fri Feb 20 11:25:11 2026 -0500

    Require Scala 2.13.16 when for Daffodil 3.11.0
    
    Scala 2.13.17 breaks serialization compatablity. Daffodil 3.11.0
    requires scala 2.13.16, but the plugin current sets scalaVersion to
    2.13.18. The causes packageDaffodilBin to create a saved parser that
    cannot be used with Daffodil 3.11.0.
    
    This issue seems to only affect Daffodil 3.11.0--all other versions of
    Scala/Daffodil seem to maintain saved parser compatability.
    
    This modifies the scalaVersion to pin the scala version to 2.13.16 when
    Daffodil version is 3.11.0. This also modifies the sbt-daffodil-utils
    project to not add a dependency to scala-library, instead assuming comes
    from Daffodil or scalaVersion, allowing control over which libary
    version is used.
    
    Update the versions-01 test to include more complexity that is known to
    cause issues with reloading saved parsers if built with newer versions
    of scala-library.
    
    Closes #163
---
 build.sbt                                          | 11 +++-
 .../scala/org/apache/daffodil/DaffodilPlugin.scala | 42 +++++++++++----
 .../src/main/resources/com/example/test.dfdl.xsd   |  9 +++-
 .../src/test/resources/com/example/input.txt       |  1 +
 .../src/test/resources/com/example/test.tdml       |  2 +-
 src/sbt-test/sbt-daffodil/versions-01/test.script  | 60 ++++++++++++++++++----
 6 files changed, 100 insertions(+), 25 deletions(-)

diff --git a/build.sbt b/build.sbt
index 4093db5..e1b3298 100644
--- a/build.sbt
+++ b/build.sbt
@@ -74,7 +74,8 @@ lazy val plugin = (project in file("."))
     // Rat check settings
     ratExcludes := Seq(
       file(".git"),
-      file("VERSION")
+      file("VERSION"),
+      
file("src/sbt-test/sbt-daffodil/versions-01/src/test/resources/com/example/input.txt")
     ),
     ratFailBinaries := true
   )
@@ -120,7 +121,13 @@ lazy val utils = (projectMatrix in file("utils"))
           )
         }
       }
-    }
+    },
+    // Do not automatically add scala-library as a dependency to the 
sbt-daffodil-utils jar. We
+    // expect scala-library to come from the provided Daffodil dependency. 
This is important
+    // because in some cases newer versions of scala-library break 
serialization compatability
+    // and the auto added version might be too new. When using 
sbt-daffodil-utils, the
+    // sbt-daffodil plugin is careful about ensuring compatability
+    autoScalaLibrary := false
   )
   .jvmPlatform(
     // We really only need Scala versions and not full ModuleIds, but using 
ModuleId.revision
diff --git a/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala 
b/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
index 1fbb960..8a83f6e 100644
--- a/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
+++ b/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
@@ -205,22 +205,38 @@ object DaffodilPlugin extends AutoPlugin {
 
   override lazy val projectSettings: Seq[Setting[_]] = Seq(
     /**
-     * Different versions of Daffodil depend on a specific major/minor version 
of Scala. For
-     * example, all versions of Daffodil 3.10.0 and older depend on Scala 
2.12.x. Note that
-     * Scala ensures binary compatibility, so we can use the latest patch 
version for any
-     * version of Daffodil, as long as we use the correct major/minor version. 
These Scala
-     * versions should be updated anytime a new patch release is made 
available to ensure we
-     * have the latest bug fixes and JDK compatibility. Note that this does 
mean that we could
-     * use a Scala version that a version of Daffodil was not released or 
tested with, but Scala
-     * backwards compatibility guarantees should prevent this from causing 
issues.
+     * Each version of Daffodil is built and tested with a specific 
major.minor.patch version of
+     * Scala. For example, Daffodil 3.10.0 was released using Scala 2.12.20. 
Although Scala
+     * ensures binary compatibility with new patch releases, it does not 
guarantee serialization
+     * compatibility, which is needed for saved parsers (for more information, 
see
+     * https://github.com/scala/docs.scala-lang/issues/1202). However, we 
sometimes need to use
+     * newer patch versions when serializing parsers to support newer versions 
of Java. For
+     * example Scala 2.12.21 is required to build saved parsers on Java 25. 
Although
+     * serialization compatibility is not guaranteed, in practice, with 
Daffodils usage of Scala
+     * this seems to be safe and we are able to use the latest patch version 
without issue.
+     *
+     * However, the one case where this is known to break is with Daffodil 
3.11.0, which uses
+     * Scala 2.13.16, and where Scala 2.13.17 breaks serialization 
compatibility. So for
+     * Daffodil 3.11.0, we pin the scalaVersion to 2.13.16. Note that this 
could mean future
+     * version of Java will not be able to create saved parsers for 3.11.0.
+     *
+     * But for all other versions of Daffodil, we can use the latest patch 
version and allow
+     * scala-steward to update them. This ensures we get the latest bug fixes 
and JDK
+     * compatibility. If a new patch release breaks serialization 
compatibility, we can pin it
+     * to the working version, which may limit JDK support.
      */
     scalaVersion := {
       // We really only need Scala versions and not full ModuleIds, but using 
ModuleId.revision
       // makes it easier for scala-steward to detect and automatically update 
the versions when
       // new Scala patch versions are released.
+      //
+      // Note that if we update one of the below scala-library versions, we 
should verify that
+      // official Daffodil releases using older versions of scala-library can 
still reload saved
+      // parsers built with this newer scalaVersion (see above note about 
serialization
+      // compatibility). See the versions-01 scripted test to how to manually 
verify this.
       val daffodilToScalaVersion = Map(
         ">=4.0.0 " -> ("org.scala-lang" % "scala3-library" % "3.3.7").revision,
-        "=3.11.0 " -> ("org.scala-lang" % "scala-library" % 
"2.13.18").revision,
+        "=3.11.0 " -> ("org.scala-lang" % "scala-library" % 
"2.13.16").revision, // scala-steward:off
         "<=3.10.0" -> ("org.scala-lang" % "scala-library" % "2.12.21").revision
       )
       filterVersions(daffodilVersion.value, daffodilToScalaVersion).head
@@ -411,8 +427,12 @@ object DaffodilPlugin extends AutoPlugin {
     libraryDependencies ++= {
       daffodilPackageBinVersions.value.flatMap { binDaffodilVersion =>
         val cfg = daffodilVersionId(binDaffodilVersion)
-        // the Daffodil dependency must ignore the scalaVersion setting and 
instead use
-        // the specific version of scala used for the binDaffodilVersion.
+        // The daffodil-core/japi dependency transitively pulls in a 
dependency to
+        // scala-library, while taking into account scalaVersion. Above, we 
are careful to set
+        // scalaVersion appropriately to ensure compatibility with 
scala-library. Also note that
+        // sbt-daffodil-utils is configured with autoScalaLibrary set to 
false, so there are no
+        // concerns of it transitively pulling in a newer version of 
scala-library that might
+        // break compatibility.
         val daffodilToPackageBinDep = Map(
           ">=4.0.0 " -> Seq(
             "org.apache.daffodil" % "daffodil-core_3" % binDaffodilVersion % 
cfg,
diff --git 
a/src/sbt-test/sbt-daffodil/versions-01/src/main/resources/com/example/test.dfdl.xsd
 
b/src/sbt-test/sbt-daffodil/versions-01/src/main/resources/com/example/test.dfdl.xsd
index dbab88c..444b899 100644
--- 
a/src/sbt-test/sbt-daffodil/versions-01/src/main/resources/com/example/test.dfdl.xsd
+++ 
b/src/sbt-test/sbt-daffodil/versions-01/src/main/resources/com/example/test.dfdl.xsd
@@ -21,6 +21,7 @@
   xmlns:xs="http://www.w3.org/2001/XMLSchema"; 
   xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/";
   xmlns:ex="http://example.com";
+  xmlns:fn="http://www.w3.org/2005/xpath-functions";
   targetNamespace="http://example.com";
   elementFormDefault="unqualified">
 
@@ -32,6 +33,12 @@
     </appinfo>
   </annotation>
 
-  <element name="test01" type="xs:string" dfdl:lengthKind="delimited" />
+  <element name="test01" type="xs:string" dfdl:lengthKind="delimited" 
dfdl:terminator="%NL;">
+    <annotation>
+      <appinfo source="http://www.ogf.org/dfdl/";>
+        <dfdl:assert test="{ fn:string-length(.) gt 0 }" />
+      </appinfo>
+    </annotation>
+  </element>
 
 </schema>
diff --git 
a/src/sbt-test/sbt-daffodil/versions-01/src/test/resources/com/example/input.txt
 
b/src/sbt-test/sbt-daffodil/versions-01/src/test/resources/com/example/input.txt
new file mode 100644
index 0000000..038d718
--- /dev/null
+++ 
b/src/sbt-test/sbt-daffodil/versions-01/src/test/resources/com/example/input.txt
@@ -0,0 +1 @@
+testing
diff --git 
a/src/sbt-test/sbt-daffodil/versions-01/src/test/resources/com/example/test.tdml
 
b/src/sbt-test/sbt-daffodil/versions-01/src/test/resources/com/example/test.tdml
index c8d3e90..b2331a1 100644
--- 
a/src/sbt-test/sbt-daffodil/versions-01/src/test/resources/com/example/test.tdml
+++ 
b/src/sbt-test/sbt-daffodil/versions-01/src/test/resources/com/example/test.tdml
@@ -24,7 +24,7 @@
 
   <parserTestCase name="test01" root="test01" 
model="/com/example/test.dfdl.xsd">
     <document>
-      <documentPart type="text">testing</documentPart>
+      <documentPart type="file">input.txt</documentPart>
     </document>
     <infoset>
       <dfdlInfoset>
diff --git a/src/sbt-test/sbt-daffodil/versions-01/test.script 
b/src/sbt-test/sbt-daffodil/versions-01/test.script
index 3ebee0b..686e56f 100644
--- a/src/sbt-test/sbt-daffodil/versions-01/test.script
+++ b/src/sbt-test/sbt-daffodil/versions-01/test.script
@@ -16,74 +16,114 @@
 ## under the License.
 ## 
 
+# Note that saved parsers are created and tested with the scalaVersion set by
+# the plugin. However, the scalaVersion can sometimes be different from the
+# actual scala-library that a version of Daffodil was built and tested with.
+# This is done intentionally to provide support for newer versions of Java, and
+# in most cases does not cause issues. But it is possible it could break
+# reloading saved parsers. So, if the plugin changes how scalaVersion is set,
+# we should uncomment the exec lines below to verify that the saved parsers
+# work with actual Daffodil releases that use possibly older scala-library
+# versions. Note that these lines are commented out because they add
+# significant time to test and really only need to be run if the scalaVersion
+# setting is updated. Note that these tests passing is not a guarantee that
+# newer Scala versions do not cause issues, but the schema used is designed to
+# detect known serialization issues.
+
 > set daffodilVersion := "4.1.0"
 > packageDaffodilBin
 $ exists target/test-0.1-daffodil410.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/4.1.0/bin/apache-daffodil-4.1.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-4.1.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-4.1.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil410.bin src/test/resources/com/example/input.txt
 > clean
 
 > set daffodilVersion := "4.0.0"
 > packageDaffodilBin
-$ exists target/test-0.1-daffodil400.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/4.0.0/bin/apache-daffodil-4.0.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-4.0.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-4.0.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil400.bin src/test/resources/com/example/input.txt
 > clean
 
 > set daffodilVersion := "3.11.0"
 > packageDaffodilBin
 $ exists target/test-0.1-daffodil3110.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/3.11.0/bin/apache-daffodil-3.11.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-3.11.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-3.11.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil3110.bin src/test/resources/com/example/input.txt
 > clean
 
 > set daffodilVersion := "3.10.0"
 > packageDaffodilBin
-$ exists target/test-0.1-daffodil3100.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/3.10.0/bin/apache-daffodil-3.10.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-3.10.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-3.10.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil3100.bin src/test/resources/com/example/input.txt
 > clean
 
 > set daffodilVersion := "3.9.0"
 > packageDaffodilBin
-$ exists target/test-0.1-daffodil390.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/3.9.0/bin/apache-daffodil-3.9.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-3.9.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-3.9.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil390.bin src/test/resources/com/example/input.txt
 > clean
 
 > set daffodilVersion := "3.8.0"
 > packageDaffodilBin
-$ exists target/test-0.1-daffodil380.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/3.8.0/bin/apache-daffodil-3.8.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-3.8.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-3.8.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil380.bin src/test/resources/com/example/input.txt
 > clean
 
 > set daffodilVersion := "3.7.0"
 > packageDaffodilBin
-$ exists target/test-0.1-daffodil370.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/3.7.0/bin/apache-daffodil-3.7.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-3.7.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-3.7.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil370.bin src/test/resources/com/example/input.txt
 > clean
 
 > set daffodilVersion := "3.6.0"
 > packageDaffodilBin
-$ exists target/test-0.1-daffodil360.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/3.6.0/bin/apache-daffodil-3.6.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-3.6.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-3.6.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil360.bin src/test/resources/com/example/input.txt
 > clean
 
 > set daffodilVersion := "3.5.0"
 > packageDaffodilBin
-$ exists target/test-0.1-daffodil350.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/3.5.0/bin/apache-daffodil-3.5.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-3.5.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-3.5.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil350.bin src/test/resources/com/example/input.txt
 > clean
 
 > set daffodilVersion := "3.4.0"
 > packageDaffodilBin
-$ exists target/test-0.1-daffodil340.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/3.4.0/bin/apache-daffodil-3.4.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-3.4.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-3.4.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil340.bin src/test/resources/com/example/input.txt
 > clean
 
 > set daffodilVersion := "3.3.0"
 > packageDaffodilBin
-$ exists target/test-0.1-daffodil330.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/3.3.0/bin/apache-daffodil-3.3.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-3.3.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-3.3.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil330.bin src/test/resources/com/example/input.txt
 > clean
 
 > set daffodilVersion := "3.2.0"
 > packageDaffodilBin
-$ exists target/test-0.1-daffodil320.bin
 > test
+# $ exec curl -L 
https://www.apache.org/dyn/closer.lua/download/daffodil/3.2.0/bin/apache-daffodil-3.2.0-bin.tgz
 -O --output-dir target/
+# $ exec tar -xvf target/apache-daffodil-3.2.0-bin.tgz -C target/
+# $ exec target/apache-daffodil-3.2.0-bin/bin/daffodil parse -P 
target/test-0.1-daffodil320.bin src/test/resources/com/example/input.txt
 > clean

Reply via email to