Problem with RMI-IIOP protocol in Jakarta transformation of OpenJDK ORB project
by Tomasz Adamski
When I was trying to establish the steps needed to transform OpenJDK
project to Jakarta namespace I noticed that a substantial part of the
codebase implements RMI-IIOP protocol (which relies on javax.rmi.*
packages). This seems tricky to
transform IMO. Although all those classes are included into the project and
technically I could just rename the package, logically it doesn't make much
sense to me because there is no such thing as jakarta.rmi and this makes
even less sense in a project whose goal is to provide interoperability.
I'm also not sure how this is supposed two work from a legal point of view:
if Jakarta allows for optional implementation of RMI-IIOP maybe I could
just leave it this way or are we legally required to get rid of all javax.*
naming from the codebase?
Regards,
Tomek
3 years, 1 month
Creating -jakarta variants of WildFly artifacts using source transformation
by Brian Stansberry
Last July, I started a thread[1] here about ways to get native jakarta
namespace variants of artifacts, which we need for our move to EE 10. One
of the items discussed there was "5) New maven module, transform source and
build". I'm posting here as a kind of status update and tutorial about that
approach.
At this point there are 11 maven modules in the WildFly main source tree[2]
that are producing artifacts using the approach described there, and there
are PRs open for at least a couple more. I have filed or soon will file
JIRAs[3] for all the remaining WF main tree's modules that produce
artifacts that WildFly Preview currently is transforming when it provisions
a server[4], so there will be more coming.
Overview
The high level overview of how these work is that a pom-only maven module
is created that corresponds to an existing module that produces an javax
artifact. The new module's pom uses the batavia maven plugin[5] (and
Eclipse Transformer under the covers) to find the source code from the
existing maven module, transform it, and write the transformed output to
the target/ dir of the new module, specifically in the
'generated-resources', 'generated-sources', 'generated-test-resources' and
'generated-test-sources' dirs. That generated source is then associated
with the overall maven execution for the module, and thereafter gets
included as part of the subsequent compile, test, package, install and
deploy goals executed for the module. So, presto we have native jakarta
source available that is then compiled and tested and used to
package/install/deploy binary, source and javadoc jars.[6]
The generated source does not get committed into the git repository. The
git repo only has the pom.
It's a common thing for generated source to be used in an artifact build;
for example it's the technique we use to generate implementation classes
from the XXXLogger interfaces we have for each of our subsystems. What
we're doing here just takes this concept to the max by generating 100% of
the source, including test source.
Tutorial
I'm going to use a PR I sent up yesterday to illustrate how to create one
of these:
https://github.com/wildfly/wildfly/pull/14822
Steps:
1) Decide whether the module you want to work on is ready. If you're not
the component lead responsible for the module, ask that lead. To see if a
module is 'ready', look at its compile time dependencies and see if it
still depends on other artifacts for which a native jakarta variant is
needed and doesn't exist yet. Ask here or in zulip if you are not sure!
Things can change quickly, and there also may be some edge cases where
you'd think you need a jakarta namespace dependency but you really don't.
If there are dependencies that are not ready yet, stop and wait until they
are available. Or be prepared for your new module to not build, at which
point you can save your work and wait.
2) Create a new dir under ee-9/source-transform for your new module. If the
module you are transforming isn't directly under the root of the WF source,
then create a matching structure under ee-9/source-transform. For example,
I created ee-9/source-transform/jpa/spi to produce a jakarta.* variant of
jpa/spi.
3) Copy the pom.xml from an *existing source-transform module* into your
new dir. Easiest is to use one that comes from a dir the same # of levels
below source-transform as your new dir, so a couple relative paths in your
new pom are correct. For my PR I copied over
https://github.com/wildfly/wildfly/blob/main/ee-9/source-transform/weld/c...
Don't start with the pom from your source input module. Unless you want to
work out how to adapt it to use the source transformation. :) Granted it's
not rocket science. But it's easier for code reviewers to look at these if
they look like the other ones.
4) Change the artifactId in your new pom to *exactly* match the artifactId
of the module you're transforming, but with "-jakarta" appended:
https://github.com/wildfly/wildfly/pull/14822/files#diff-d9ae5e5e0388bc9e...
5) Change the 'name' tag to something appropriate, like
https://github.com/wildfly/wildfly/pull/14822/files#diff-d9ae5e5e0388bc9e...
6) Change the 'transformer-input-dir' maven property to point to the root
of the module you are transforming:
https://github.com/wildfly/wildfly/pull/14822/files#diff-d9ae5e5e0388bc9e...
This property is used in the batavia maven plugin config in the parent
source-transform dir. Each child module sets the property to point to the
correct input source for that module.
This one small tweak is the only thing you need to deal with to get the
source transformation set up.
7) Configure dependencies.
a) Delete the existing 'dependency' entries in your new pom, as they are
for whatever random file you copied in.
b) Copy over the 'dependency' entries from the pom of the module you are
transforming.
c) For any entries where your new artifact uses a dependency with a
different groupId:artifactId from the one you're transforming, change the
GA. For example:
EE 8 JTA
https://github.com/wildfly/wildfly/blob/25.0.0.Final/jpa/spi/pom.xml#L58
became EE 9.1 JTA
https://github.com/wildfly/wildfly/pull/14822/files#diff-d9ae5e5e0388bc9e...
Or, in another example
an EE 8 based 'ee' subsystem module dep:
https://github.com/wildfly/wildfly/blob/25.0.0.Final/ee-security/pom.xml#L45
became instead a dep on the new '-jakarta' variant:
https://github.com/wildfly/wildfly/pull/14652/files#diff-7ed0e6e85369889b...
d) A nice to have is to separate from the others in the dependency listing
deps where WF Preview is using a different artifact from what standard WF
is using. For example see
https://github.com/wildfly/wildfly/pull/14822/files#diff-d9ae5e5e0388bc9e...
This separation helps code reviewers.
8) Tell your new module's parent to include it in the build:
https://github.com/wildfly/wildfly/pull/14822/files#diff-37dfe0d6acd41e18...
9) The ee-9/pom.xml maintains a dependencyManagement set for all artifacts
that differ in WF Preview from what is in standard WF. These can either be
artifacts whose GA is not used at all in standard WF, or ones where WF
Preview uses a different version. Add your new artifact to this
dependencyManagement:
https://github.com/wildfly/wildfly/pull/14822/files#diff-5ddee375313bf441...
10) Allow re-use of the module.xml that incorporates this artifact between
standard WF and WF Preview. This is done by modifying the module.xml to add
an expression that the maven-resource-plugin replaces when preparing the
module.xml resource file for use in the FP build:
https://github.com/wildfly/wildfly/pull/14822/files#diff-f89017fad51e240c...
The added @module.jakarta.suffix@ gets replaced either with an empty string
(standard WF) or "-jakarta" (WF Preview)
11) Add your new artifact as a dependency of ee-9/feature-pack/pom.xml.
This is needed so the wildfly-preview Galleon feature pack can utilize your
new artifact:
https://github.com/wildfly/wildfly/pull/14822/files#diff-1375aa050fa94d63...
12) Tell the wildfly-preview feature-pack build to ignore the no-longer
relevant javax artifact you're replacing. This saves build time, compute
resources and false positives in the build log that make us think your
artifact hasn't been handled yet.
https://github.com/wildfly/wildfly/pull/14822/files#diff-1375aa050fa94d63...
(Note the precise spot to put that 'exclude' may differ, a bit. Ask if this
is unclear.)
13) Add an entry for your new artifact in the license.xml file for the
wildfly-preview feature back. Put it in the right alphabetical spot based
on its groupId and artifactId.
https://github.com/wildfly/wildfly/pull/14822/files#diff-11ae0f2f274afa8c...
14) Do a build and if good, commit and send up a PR! If your input module
had tests, your new module should as well and they should run. If you're
curious, have a look in the new target/generated-xxx dirs to see the
source..
This sounds like a lot, and I suppose it is, but other than step 7) it's
all very simple stuff, mostly things you'd do any time you add a new module
to the WF source tree. Granted I'm practiced at this, but it took me about
half an hour to work up the PR I've been using as an example.
If you're interested in doing one of these, and the component lead
responsible for the input module is agreeable, please go for it and feel
free to ask for help.
[1]
https://lists.jboss.org/archives/list/wildfly-dev@lists.jboss.org/thread/...
[2] Child modules under
https://github.com/wildfly/wildfly/tree/main/ee-9/source-transform
[3] High level tracker issues for this work are
https://issues.redhat.com/browse/WFLY-15436 and
https://issues.redhat.com/browse/WFLY-15437. I'm filing separate issues for
individual pieces and am linking those to one or the other of these two
trackers.
[4]
https://docs.google.com/spreadsheets/d/1TekfyRb2UBCLqsPQ83WTg8XOw9qwuHVSh...
shows all artifacts (not just those from the WF source tree) that the
WildFly Galleon plugin was transforming in builds on Oct 14. The rows that
end with '-26.0.0.Beta1-SNAPSHOT.jar' are ones that are produced by WildFly
main itself. I add new tabs to that document weekly to track progress on
reducing the # of artifacts being transformed by the Galleon plugin.
[5]
https://github.com/wildfly/wildfly/blob/main/ee-9/source-transform/pom.xm...
[6]
https://repository.jboss.org/org/wildfly/wildfly-mail-jakarta/25.0.0.Final/
which was produced from a maven module with nothing in it but a pom.
Best regards,
--
Brian Stansberry
Project Lead, WildFly
He/Him/His
3 years, 1 month
JDK 18 Early-Access builds 23 are available
by David Delabassee
David, Richard,
I’m happy to announce that moving forward Oracle’s Java DevRel Team will manage the Quality Outreach Program. I would like to thank Rory for all the efforts he's put into this program and wish him all the joy and happiness that retirement can bring! We have big shoes to fill but we’re excited to continue building off the amazing structure Rory has put in place.
The JDK 18 schedule is now known [1] with a feature freeze date (Rampdown Phase One) less than 4 weeks away! This time, we have 2 important heads-ups, one related to JEP 411 (Deprecate the Security Manager for Removal), and one related to JEP 416 (Reimplement Core Reflection with Method Handles). We're asking your help to test and confirm that your project works seamlessly now that those 2 JEPs are integrated in the JDK 18 Early-Access builds.
[1] https://openjdk.java.net/projects/jdk/18/
# JEP 411 - Deprecate the Security Manager for Removal
Starting JDK 18 b21 [2], the default value of the 'java.security.manager' system property is set to "disallow". This means that any application or library that enables the Security Manager by calling `System.setSecurityManager` will now have to specify `-Djava.security.manager=allow` on the command-line in order for that code to continue working as expected. This change was originally targeted for JDK 17, but after some discussion/feedback from the community, the change was delayed until JDK 18 [3].
[2] https://bugs.openjdk.java.net/browse/JDK-8270380
[3] https://openjdk.java.net/jeps/411#Description
# JEP 416 - Reimplement Core Reflection with Method Handles
JEP 416 [4] reimplements `java.lang.reflect.Method`, `java.lang.reflect.Constructor`, and `java.lang.reflect.Field` on top of `java.lang.invoke` method handles. Making method handles the underlying mechanism for reflection will reduce the maintenance and development cost of both the `java.lang.reflect` and `java.lang.invoke` APIs. This is solely an implementation change but we encourage you to test your project to identify any behavior or performance regressions.
[4] https://openjdk.java.net/jeps/416
OpenJDK 18 Early-Access builds 23 are now available [5], and are provided under the GNU General Public License v2, with the Classpath Exception. The Release Notes are available [6].
[5] https://jdk.java.net/18/
[6] https://jdk.java.net/18/release-notes
# JEPs integrated to JDK 18, so far:
- JEP 400: UTF-8 by Default https://openjdk.java.net/jeps/400
- JEP 408: Simple Web Server https://openjdk.java.net/jeps/408
- JEP 413: Code Snippets in Java API Documentation https://openjdk.java.net/jeps/413
- JEP 416: Reimplement Core Reflection with Method Handles https://openjdk.java.net/jeps/416
- JEP 418: Internet-Address Resolution SPI https://openjdk.java.net/jeps/418
# JEPs targeted to JDK 18, so far:
- JEP 417: Vector API (Third Incubator) https://openjdk.java.net/jeps/417
# JEPs proposed to target JDK 18, so far:
- JEP 419: Foreign Function & Memory API (Second Incubator) https://openjdk.java.net/jeps/419
- JEP 420: Pattern Matching for switch (Second Preview) https://openjdk.java.net/jeps/420
# Changes in recent builds that maybe of interest:
## Build 23:
- JDK-8275509: ModuleDescriptor.hashCode isn't reproducible across builds
- JDK-8276220: Reduce excessive allocations in DateTimeFormatter
- JDK-8276298: G1: Remove unused G1SegmentedArrayBufferList::add
- JDK-8273922: (fs) UserDefinedFileAttributeView doesn't handle file names that are just under the MAX_PATH limit (win)
## Build 22:
- JDK-8271820: Implementation of JEP 416: Reimplement Core Reflection with Method Handle
- JDK-8260428: Drop support for pre JDK 1.4 DatagramSocketImpl implementations
- JDK-8251468: X509Certificate.get{Subject,Issuer}AlternativeNames and getExtendedKeyUsage do not throw CertificateParsingException if extension is unparseable
## Build 21:
- JDK-8270380: Change the default value of the java.security.manager system property to disallow
- JDK-8275319: java.net.NetworkInterface throws java.lang.Error instead of SocketException
- JDK-8270490: Charset.forName() taking fallback default value
- JDK-8269336: Malformed jdk.serialFilter incorrectly handled
# Project Loom update
New Project Loom 18-loom+4-273 (2021/11/10) Early-Access builds are available [7] with related Javadocs [8].
[7] https://jdk.java.net/loom/
[8] https://download.java.net/java/early_access/loom/docs/api/
These EA builds are provided under the GNU General Public License, version 2, with the Classpath Exception and are produced for the purpose of gathering feedback. Use for any other purpose is at your own risk. Feedback should be send to the `loom-dev` mailing list (https://mail.openjdk.java.net/mailman/listinfo/loom-dev).
# Topics of Interest:
* New Candidate JEP: 421: Deprecate Finalization for Removal, https://openjdk.java.net/jeps/421
* What Happens to Finalization in JDK 18 and JEP 416 - Inside Java Newscast, https://youtu.be/eDgBnjOid-g
Thank you for being a welcomed part of the Quality Outreach program!
--
David Delabassée / @delabassee
3 years, 1 month
Resolving credential store expressions in deployment descriptors and deployment annotation values
by Brian Stansberry
We're currently missing $subject in WildFly and I'd like to add it in. I
regard this absence as a bug, as expression resolution functionality should
be consistent between expressions in deployment resources and those in the
management model.
The biggest hurdle to doing this is that ElytronExpressionResolver, the class
that resolves credential store expressions, requires access to an
OperationContext to do resolution, and that is not available when resolving
these deployment resource expressions. It needs the OperationContext for
what I think are 3 basic reasons:
1) So objects it uses can get the PathManager to resolve paths.
2) So it or objects it uses can resolve capabilities, e.g. to get the
runtime api exposed by the relevant credential store, which in turn does
something similar with providers.
3) So it and objects it uses can resolve their configuration settings from
the management model and initialize themselves.
The last bit is interesting as those classes can't *solely* rely on a
Stage.RUNTIME step from the OSH that adds their config model. During
parallel boot, threads that are initializing other subsystems in
Stage.RUNTIME concurrently with a different thread that is initializing the
elytron subsystem may need to initialize these objects using their own
thread's OperationContext. For example, they may need to resolve a
credential store expression in their own config model.
A key design point for what I have in mind is that AIUI there is no reason
all this initialization work can't be completed before an operation
(including boot) proceeds to dealing with deployments. During boot we do
all the Stage.RUNTIME work for subsystems before proceeding to deployments.
After boot, people creating an operation with a step that deploys a
deployment that uses a credential store expression must ensure the relevant
credential store resolver has been added first.
So, what I'm thinking of doing is:
A) Abstract the internal uses of OperationContext behind an interface, with
impls backed by either an OperationContext or a CapabilityServiceSupport.
Methods the CapabilityServiceSupport-backed impl can't support (resolving
config values) will fail in javadoced manner, probably an ISE. Callers deal
with the failure appropriately. I *believe* once all is done any such
failure would indicate a bug in WF, i.e. that things that should have been
initialized before deployment work starts haven't been.
B) Where this doesn't already happen, ensure that any Elytron resource that
adds one of these objects that gets initialized via the A) interface gets
initialized by the OperationContext that adds the resource (if some other
OperationContext hasn't already done so.) For sure
ExpressionResolverResourceDefinition
will need to be updated to ensure ElytronExpressionResolver is initialized
along with any credential stores it may rely upon. (I'm thinking of doing
this by having a Stage.RUNTIME OSH ask the ElytronExpressionResolver to
create an expression using each configured resolver.)
C) For the PathManager case, either have the impls behind A) look up the
PathManager via a capability, or make the PathManager available from the
ExtensionContext on host processes (currently it is only available there on
servers) and have that injected into the impls.
D) Add a deployment AttachmentKey that exposes an object that the EE
subsystem can use to wire credential store expression support into the
existing deployment expression resolution, a la what we did before with
vault expression resolution. Elytron subsystem would attach the object.
Probably the object would be a BiFunction<String, CapabilityServiceSupport,
String>. Perhaps we could expose this via a capability, but using a
deployment processing attachment restricts the exposure of the object to
deployment processing.
Feedback is welcome!
Best regards,
--
Brian Stansberry
Project Lead, WildFly
He/Him/His
3 years, 1 month