Conversation
|
So, if we want to export OSGi meta-data alongside our JPMS module I thought OSGi had even added support for JPMS, but I could be mistaken-remembering, it had been a while since I messed with this stuff. |
|
Trying to generate anything would mean a bigger change in the build scripts, probably switching to https://plugins.gradle.org/plugin/biz.aQute.bnd.builder. I can try doing that, if it has a chance of being potentially approved. |
|
Played with BND a bit and I am pretty convinced that the only way to keep module-info.java and OSGi metadata in sync is to actually let BND generate both and ideally using its annotation system (https://bnd.bndtools.org/chapters/230-manifest-annotations.html). |
7ce4855 to
1e7bc14
Compare
|
I have added metadata for rhino-xml and fixed cardinality and resolution attributes. I have also wrote unit test that checks what can be checked. Ideally this should be accompanied with |
1e7bc14 to
aee7dea
Compare
|
I have prepared feature branch for backporting this to 1.9 - https://github.com/pavelhoral/rhino/tree/feat-osgi-1_9. |
|
Does anyone else have experience with BND? If it's a straightforward Gradle plugin, and it lets us generate both Java module config and Osgi metadata from a single source, I'm all for it if you're willing to put together a PR. |
|
I have (with help from Claude Code and a lot of double-checking) switched OSGi metadata and JPMS module info build to BND plugin. Generated change summary:
I have intentionally added this change as a separate commit from my previous changes that only added OSGi metadata and did not touch Generated script for extracting JPMS and OSGi metadata: JPMS differencesdiff --git a/jpms-before.txt b/jpms-after.txt
index 0622aa2..dd50cca 100644
--- a/jpms-before.txt
+++ b/jpms-after.txt
@@ -1,5 +1,5 @@
=== rhino ===
-org.mozilla.rhino
+org.mozilla.rhino@2.0.0.SNAPSHOT
exports org.mozilla.classfile
exports org.mozilla.javascript
exports org.mozilla.javascript.annotations
@@ -13,52 +13,62 @@ exports org.mozilla.javascript.optimizer
exports org.mozilla.javascript.serialize
exports org.mozilla.javascript.typedarrays
exports org.mozilla.javascript.xml
-requires java.base mandated
+requires java.base
requires java.compiler
-requires java.desktop transitive
-requires jdk.dynalink
+requires java.desktop static
+requires jdk.dynalink static
uses org.mozilla.javascript.NullabilityDetector
uses org.mozilla.javascript.RegExpLoader
uses org.mozilla.javascript.config.RhinoPropertiesLoader
uses org.mozilla.javascript.xml.XMLLoader
provides org.mozilla.javascript.RegExpLoader with org.mozilla.javascript.regexp.RegExpLoaderImpl
+contains org.mozilla.javascript.dtoa
+contains org.mozilla.javascript.json
+contains org.mozilla.javascript.lc
+contains org.mozilla.javascript.lc.member
+contains org.mozilla.javascript.lc.type.impl
+contains org.mozilla.javascript.lc.type.impl.factory
contains org.mozilla.javascript.regexp
+contains org.mozilla.javascript.resources
+contains org.mozilla.javascript.v8dtoa
=== rhino-engine ===
-org.mozilla.rhino.engine@2.0.0-SNAPSHOT
+org.mozilla.rhino.engine@2.0.0.SNAPSHOT
exports org.mozilla.javascript.engine
-requires java.base mandated
+requires java.base
requires java.scripting transitive
requires org.mozilla.rhino transitive
provides javax.script.ScriptEngineFactory with org.mozilla.javascript.engine.RhinoScriptEngineFactory
=== rhino-tools ===
-org.mozilla.rhino.tools@2.0.0-SNAPSHOT
+org.mozilla.rhino.tools@2.0.0.SNAPSHOT
exports org.mozilla.javascript.tools
exports org.mozilla.javascript.tools.debugger
exports org.mozilla.javascript.tools.jsc
exports org.mozilla.javascript.tools.shell
-requires java.base mandated
-requires java.desktop transitive
+requires java.base
+requires java.desktop static
requires org.jline.reader static
requires org.jline.terminal static
requires org.mozilla.rhino transitive
uses org.mozilla.javascript.tools.ConsoleProvider
provides org.mozilla.javascript.tools.ConsoleProvider with org.mozilla.javascript.tools.shell.BasicConsoleProvider org.mozilla.javascript.tools.shell.JLineConsoleProvider
+contains org.mozilla.javascript.tools.debugger.treetable
+contains org.mozilla.javascript.tools.resources
main-class org.mozilla.javascript.tools.shell.Main
=== rhino-xml ===
-org.mozilla.javascript.xml@2.0.0-SNAPSHOT
+org.mozilla.javascript.xml@2.0.0.SNAPSHOT
exports org.mozilla.javascript.xmlimpl
-requires java.base mandated
+requires java.base
requires java.xml transitive
requires org.mozilla.rhino transitive
provides org.mozilla.javascript.xml.XMLLoader with org.mozilla.javascript.xmlimpl.XMLLoaderImpl
=== rhino-kotlin ===
-org.mozilla.rhino.kotlin@2.0.0-SNAPSHOT
+org.mozilla.rhino.kotlin@2.0.0.SNAPSHOT
exports org.mozilla.kotlin
-requires java.base mandated
+requires java.base
requires kotlin.metadata.jvm
requires kotlin.stdlib
requires org.mozilla.rhino
OSGi differences (from what my previous commit was generating)diff --git a/osgi-before.txt b/osgi-after.txt
index 9f5e77b..4a72443 100644
--- a/osgi-before.txt
+++ b/osgi-after.txt
@@ -1,7 +1,36 @@
=== rhino ===
Bundle-SymbolicName org.mozilla.rhino
-Bundle-Version 2.0.0
+Bundle-Version 2.0.0.SNAPSHOT
DynamicImport-Package *
+Import-Package
+ android.os {resolution:=optional}
+ java.beans {resolution:=optional}
+ java.io
+ java.lang
+ java.lang.annotation
+ java.lang.invoke
+ java.lang.ref
+ java.lang.reflect
+ java.math
+ java.net
+ java.nio.charset
+ java.security
+ java.text
+ java.time
+ java.time.format
+ java.time.temporal
+ java.util
+ java.util.concurrent
+ java.util.concurrent.atomic
+ java.util.concurrent.locks
+ java.util.function
+ java.util.jar
+ java.util.regex
+ java.util.stream
+ jdk.dynalink {resolution:=optional}
+ jdk.dynalink.linker {resolution:=optional}
+ jdk.dynalink.linker.support {resolution:=optional}
+ jdk.dynalink.support {resolution:=optional}
Export-Package
org.mozilla.classfile {version=2.0.0}
org.mozilla.javascript {version=2.0.0}
@@ -17,70 +46,130 @@ Export-Package
org.mozilla.javascript.typedarrays {version=2.0.0}
org.mozilla.javascript.xml {version=2.0.0}
Provide-Capability
- osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.RegExpLoader}
+ osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.RegExpLoader, register:=org.mozilla.javascript.regexp.RegExpLoaderImpl}
Require-Capability
osgi.ee {filter:=(&(osgi.ee=JavaSE)(version>=11))}
osgi.extender {filter:=(osgi.extender=osgi.serviceloader.processor)}
osgi.extender {filter:=(osgi.extender=osgi.serviceloader.registrar)}
- osgi.serviceloader {filter:=(osgi.serviceloader=org.mozilla.javascript.RegExpLoader)}
- osgi.serviceloader {filter:=(osgi.serviceloader=org.mozilla.javascript.NullabilityDetector), resolution:=optional}
- osgi.serviceloader {filter:=(osgi.serviceloader=org.mozilla.javascript.config.RhinoPropertiesLoader), resolution:=optional}
- osgi.serviceloader {filter:=(osgi.serviceloader=org.mozilla.javascript.xml.XMLLoader), resolution:=optional}
+ osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.RegExpLoader}
+ osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.NullabilityDetector, resolution:=optional}
+ osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.config.RhinoPropertiesLoader, resolution:=optional}
+ osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.xml.XMLLoader, resolution:=optional}
=== rhino-engine ===
Bundle-SymbolicName org.mozilla.rhino.engine
-Bundle-Version 2.0.0
+Bundle-Version 2.0.0.SNAPSHOT
Import-Package
+ java.io
+ java.lang
+ java.lang.invoke
+ java.lang.reflect
+ java.nio.charset
+ java.util
javax.script
- org.mozilla.javascript {version=2.0.0}
+ org.mozilla.javascript {version=[2.0,3)}
Export-Package
org.mozilla.javascript.engine {version=2.0.0}
Provide-Capability
- osgi.serviceloader {osgi.serviceloader=javax.script.ScriptEngineFactory}
+ osgi.serviceloader {osgi.serviceloader=javax.script.ScriptEngineFactory, register:=org.mozilla.javascript.engine.RhinoScriptEngineFactory}
Require-Capability
osgi.ee {filter:=(&(osgi.ee=JavaSE)(version>=11))}
osgi.extender {filter:=(osgi.extender=osgi.serviceloader.registrar)}
=== rhino-tools ===
Bundle-SymbolicName org.mozilla.rhino.tools
-Bundle-Version 2.0.0
+Bundle-Version 2.0.0.SNAPSHOT
Import-Package
- org.jline.reader {resolution:=optional}
- org.jline.terminal {resolution:=optional}
- org.mozilla.javascript {version=2.0.0}
- org.mozilla.javascript.commonjs.module {version=2.0.0}
- org.mozilla.javascript.commonjs.module.provider {version=2.0.0}
- org.mozilla.javascript.config {version=2.0.0}
- org.mozilla.javascript.debug {version=2.0.0}
- org.mozilla.javascript.optimizer {version=2.0.0}
- org.mozilla.javascript.serialize {version=2.0.0}
+ java.awt {resolution:=optional}
+ java.awt.event {resolution:=optional}
+ java.awt.geom {resolution:=optional}
+ java.io
+ java.lang
+ java.lang.invoke
+ java.lang.ref
+ java.lang.reflect
+ java.net
+ java.nio.charset
+ java.security
+ java.security.cert
+ java.text
+ java.util
+ java.util.regex
+ javax.swing {resolution:=optional}
+ javax.swing.border {resolution:=optional}
+ javax.swing.event {resolution:=optional}
+ javax.swing.filechooser {resolution:=optional}
+ javax.swing.table {resolution:=optional}
+ javax.swing.text {resolution:=optional}
+ javax.swing.tree {resolution:=optional}
+ org.jline.reader {version=[3.30,4), resolution:=optional}
+ org.jline.terminal {version=[3.30,4), resolution:=optional}
+ org.mozilla.javascript {version=[2.0,3)}
+ org.mozilla.javascript.commonjs.module {version=[2.0,3)}
+ org.mozilla.javascript.commonjs.module.provider {version=[2.0,3)}
+ org.mozilla.javascript.config {version=[2.0,3)}
+ org.mozilla.javascript.debug {version=[2.0,3)}
+ org.mozilla.javascript.optimizer {version=[2.0,3)}
+ org.mozilla.javascript.serialize {version=[2.0,3)}
Export-Package
org.mozilla.javascript.tools {version=2.0.0}
org.mozilla.javascript.tools.debugger {version=2.0.0}
org.mozilla.javascript.tools.jsc {version=2.0.0}
org.mozilla.javascript.tools.shell {version=2.0.0}
Provide-Capability
- osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.tools.ConsoleProvider}
+ osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.tools.ConsoleProvider, register:=org.mozilla.javascript.tools.shell.BasicConsoleProvider}
+ osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.tools.ConsoleProvider, register:=org.mozilla.javascript.tools.shell.JLineConsoleProvider}
Require-Capability
osgi.ee {filter:=(&(osgi.ee=JavaSE)(version>=11))}
osgi.extender {filter:=(osgi.extender=osgi.serviceloader.processor)}
osgi.extender {filter:=(osgi.extender=osgi.serviceloader.registrar)}
- osgi.serviceloader {filter:=(osgi.serviceloader=org.mozilla.javascript.tools.ConsoleProvider), cardinality:=multiple}
+ osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.tools.ConsoleProvider, cardinality:=multiple}
=== rhino-xml ===
-Bundle-SymbolicName org.mozilla.rhino.engine
-Bundle-Version 2.0.0
+Bundle-SymbolicName org.mozilla.rhino.xml
+Bundle-Version 2.0.0.SNAPSHOT
Import-Package
- javax.script
- org.mozilla.javascript {version=2.0.0}
- org.mozilla.javascript.xml {version=2.0.0}
+ java.io
+ java.lang
+ java.lang.invoke
+ java.util
+ java.util.concurrent
+ javax.xml.parsers
+ javax.xml.transform
+ javax.xml.transform.dom
+ javax.xml.transform.stream
+ org.mozilla.javascript {version=[2.0,3)}
+ org.mozilla.javascript.xml {version=[2.0,3)}
+ org.w3c.dom
+ org.xml.sax
Export-Package
org.mozilla.javascript.xmlimpl {version=2.0.0}
Provide-Capability
- osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.xml.XMLLoader}
+ osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.xml.XMLLoader, register:=org.mozilla.javascript.xmlimpl.XMLLoaderImpl}
Require-Capability
osgi.ee {filter:=(&(osgi.ee=JavaSE)(version>=11))}
osgi.extender {filter:=(osgi.extender=osgi.serviceloader.registrar)}
=== rhino-kotlin ===
+Bundle-SymbolicName org.mozilla.rhino.kotlin
+Bundle-Version 2.0.0.SNAPSHOT
+Import-Package
+ java.lang
+ java.lang.annotation
+ java.lang.invoke
+ java.lang.reflect
+ java.util
+ java.util.function
+ java.util.stream
+ kotlin
+ kotlin.metadata
+ kotlin.metadata.jvm
+ org.mozilla.javascript {version=[2.0,3)}
+Export-Package
+ org.mozilla.kotlin {version=2.0.0}
+Provide-Capability
+ osgi.serviceloader {osgi.serviceloader=org.mozilla.javascript.NullabilityDetector, register:=org.mozilla.kotlin.KotlinNullabilityDetector}
+Require-Capability
+ osgi.ee {filter:=(&(osgi.ee=JavaSE)(version>=11))}
+ osgi.extender {filter:=(osgi.extender=osgi.serviceloader.registrar)} |
|
Thanks! Two things: First of all, my AI found two regressions in the module file when I asked it to compare before and after and I think it's right: Second, how do we verify that the OSGi manifests are right? The way we have it now, if someone makes a mistake in a module specification then tests will fail (because we run many of the tests in a module themselves). If someone makes a mistake in the OSGi bit in the future, how do we catch it? I think you had a previous version of this PR that had some tests. |
This is intentional as described in the summary I posted. I wanted the
Properly testing would require testing in OSGi environment. I can try to create some Apache Felix test if that is required, but it probably wouldn't be that lightweight.
Here be careful, because my change removed the modules from tests AFAIK! There was a intermediate step, where I had both Question here is whether you really want to run all unit tests under JPMS, or if you just want some lightweight integration smoke test that will verify modules work together. |
|
Playing with it a bit more -> when the tests are run with JPMS, they fail as the |
|
I have pushed one additional commit that adds integration tests for JPMS and OSGi. These tests are intentionally separate from the pre-existing unit tests as they depend on the built JAR files. This setup makes much more sense to me (intentional testing of JPMS and OSGi) than what was done previously -> running all unit tests as JPMS modules. Summary generated by ClaudeJPMS and OSGi integration testsDedicated integration tests verify that Rhino's BND-generated module metadata works correctly in real JPMS and OSGi environments. These tests run against the built JARs (not classes directories) and are separated from regular unit tests so that RunningThis is also included in Build setupA dedicated Apache Felix ( JpmsModuleTestTests JPMS module behavior in-process using the Tests:
OsgiModuleTestTests OSGi bundle behavior by embedding an Apache Felix framework, installing the built JARs as bundles, and verifying resolution, activation, and cross-bundle wiring. The Tests:
|
This is a different attempt on #1278.
RegExpLoader).Disclamer: I got help from Claude Code, but I have verified that the bundles correctly load and work in my OSGi environment. I have tested the OSGi bundles on
rhino_1_9_1branch - would be nice to get this backported as OSGi does not like major version changes).