This is a vote to release the Apache Log4j Scala 13.0.0. Website: https://logging.staged.apache.org/log4j/scala GitHub: https://github.com/apache/logging-log4j-scala Commit: 980f4ed0ba53f93d1514df65ddafb6f97396a975 Distribution: https://dist.apache.org/repos/dist/dev/logging/log4j-scala Nexus: https://repository.apache.org/content/repositories/orgapachelogging-1200 Signing key: 0x077e8893a6dcc33dd4a4d5b256e73ba9a0b592d0
Please download, test, and cast your votes on this mailing list. [ ] +1, release the artifacts [ ] -1, don't release, because... This vote is open for 72 hours and will pass unless getting a net negative vote count. All votes are welcome and we encourage everyone to test the release, but only the Logging Services PMC votes are officially counted. At least 3 +1 votes and more positive than negative votes are required. === Reproducibility The `log4j-api-scala_3.jar` artifact targeting Scala 3 in this release is not reproducible due to a bug in the Scala 3 compiler[1]. (The other 4 artifacts are reproducible!) Though I don't find this a release blocker since we can verify that the difference breaking the reproducibility is just a member ordering problem, which doesn't have any practical effect from a user's point of view. [1] https://github.com/lampepfl/dotty/issues/18248 ==== What about CI checks? Note that CI-based reproducibility checks pass, since the issue appears to be only observable when sources are built on hosts with different specs. ==== How can I check the reproducibility myself? export NEXUS_REPO=https://repository.apache.org/content/repositories/orgapachelogging-1200 ./mvnw verify artifact:compare -Dreference.repo=$NEXUS_REPO ==== How can I view the difference myself? ./mvnw package mkdir t && cd $_ wget https://repository.apache.org/content/repositories/orgapachelogging-1200/org/apache/logging/log4j/log4j-api-scala_3/13.0.0/log4j-api-scala_3-13.0.0.jar unzip log4j-api-scala_3-13.0.0.jar -d reference unzip ../log4j-api-scala_3/target/log4j-api-scala_3-13.0.0.jar -d local diff -r reference local # `diff` will point out that only `LoggingContext$.class` doesn't match javap 'reference/org/apache/logging/log4j/scala/LoggingContext$.class' > reference.LoggingContext javap 'local/org/apache/logging/log4j/scala/LoggingContext$.class' > local.LoggingContext diff -u reference.LoggingContext local.LoggingContext ==== What is the difference? Decompiling and comparing `LoggingContext$.class` files produce the following output: --- reference.LoggingContext 2023-10-10 12:58:35.188544183 +0200 +++ local.LoggingContext 2023-10-10 12:58:41.152551071 +0200 @@ -114,30 +114,30 @@ public scala.collection.LazyZip2 lazyZip(scala.collection.Iterable); public scala.collection.IterableFactory iterableFactory(); public scala.Function1 compose(scala.Function1); - public double apply$mcDI$sp(int); - public double apply$mcDJ$sp(long); - public double apply$mcDF$sp(float); - public double apply$mcDD$sp(double); + public int apply$mcII$sp(int); + public int apply$mcIJ$sp(long); + public int apply$mcIF$sp(float); + public int apply$mcID$sp(double); public boolean apply$mcZI$sp(int); public boolean apply$mcZJ$sp(long); public boolean apply$mcZF$sp(float); public boolean apply$mcZD$sp(double); - public long apply$mcJI$sp(int); - public long apply$mcJJ$sp(long); - public long apply$mcJF$sp(float); - public long apply$mcJD$sp(double); - public void apply$mcVI$sp(int); - public void apply$mcVJ$sp(long); - public void apply$mcVF$sp(float); - public void apply$mcVD$sp(double); public float apply$mcFI$sp(int); public float apply$mcFJ$sp(long); public float apply$mcFF$sp(float); public float apply$mcFD$sp(double); - public int apply$mcII$sp(int); - public int apply$mcIJ$sp(long); - public int apply$mcIF$sp(float); - public int apply$mcID$sp(double); + public void apply$mcVI$sp(int); + public void apply$mcVJ$sp(long); + public void apply$mcVF$sp(float); + public void apply$mcVD$sp(double); + public double apply$mcDI$sp(int); + public double apply$mcDJ$sp(long); + public double apply$mcDF$sp(float); + public double apply$mcDD$sp(double); + public long apply$mcJI$sp(int); + public long apply$mcJJ$sp(long); + public long apply$mcJF$sp(float); + public long apply$mcJD$sp(double); public scala.Option unapply(java.lang.Object); public scala.PartialFunction elementWise(); public scala.PartialFunction orElse(scala.PartialFunction); ==== Why is it a simple ordering problem? Since `grep -E 'public (.+) apply\$' | sort` executed against both `reference.LoggingContext` and `local.LoggingContext` produce the same output. === Release Notes The highlights of this major release are Scala 3 support, JPMS descriptors, and the switch to semantic versioning[2]. [2] https://semver.org Note that this release is still binary backward compatible with the earlier release `12.0`. Though we needed to bump the major version number for the semantic versioning switch to avoid the confusion related with version ordering. ==== Added * Added support for Scala 3 (LOG4J2-3184, #26) * Added OSGi and JPMS support ==== Changed * Bumped the Java version to 17 (Scala 2.10 and 2.11 targets still require Java 8 that build switches to using `maven-toolchains-plugin`) * Switch the CI to GitHub Actions * Switched from `sbt` to Maven to take advantage of `logging-parent` conveniences * Switched to semantic versioning * Updated `org.apache.logging.log4j:log4j-api` version to `2.20.0` * Update `org.apache.logging:logging-parent` to version `10.1.1` * Started using `log4j-changelog`