phax / ph-jaxb-pom

A simple POM wrapper to consistently include JAXB 2.2 and 2.3
Apache License 2.0
0 stars 0 forks source link

Remove runtime dependency for JAXB #1

Closed T3rm1 closed 3 years ago

T3rm1 commented 3 years ago

The runtime dependency is included with compile scope right now. This is not correct and causes issues in projects that use your library. You should only rely on the api, not the runtime.

See below example: image Using ph-ubl21 will load the runtime. Instead only the api should be a dependency and the runtime has to be taken care of by the user who uses this project.

phax commented 3 years ago

Hi @T3rm1 I totally understand that question. As long as you are only using Java 8 this is not necessary, but as soon as you swutch to a newer version (Java 9 or later) that explicit dependency is needed to keep the applications working.

T3rm1 commented 3 years ago

The JAXB runtime was removed from the JDK from 9 onwards. You provide a library that is used in an application. The library should never include any dependencies that are only required at runtime (use jaxb-api). That's the responsibility of the application.

phax commented 3 years ago

Point taken. So you effectively want to use a different implementation?

T3rm1 commented 3 years ago

Yes, I think a lot of people use the Glassfish reference implementation nowadays. Admittedly I found very little information how they differ. Both seem to be still actively developed.

phax commented 3 years ago

So the "com.sun.xml.bind" is the reference implementation, even though I understand that it is confusing. JAXB is now handled by the Jakarta project: https://eclipse-ee4j.github.io/jaxb-ri/

When you include version 3 of the com.sun.xml.bind module like this

  <dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>3.0.1</version>
  </dependency>

you get these JAXB things: grafik

If you instead include this from the Glassfish package (called jaxb-runtime instead of jaxb-impl):

  <dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>3.0.1</version>
  </dependency>

you get these packages: grafik

so you can see, the jaxb-impl and the jaxb-runtime module is the same - independent of the Maven group ID you are using. It seems to be just "repackaged". The only difference is in the jaxb-core modules, where the com.sun ones include istack whereas the Glassfish ones need this as a dependency.

For Version 2.x (which is required when you want to use Java 8 in combination with JAXWS), include this

  <dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.3.3</version>
  </dependency>

and you get these packages: grafik

Compare to the Glassfish one:

  <dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.3</version>
  </dependency>

you get these packages: grafik

Again the difference is the inclusion of istack.

So my conclusion is, that the usage of the "com.sun" module is fine, because it spares one additional dependency.

T3rm1 commented 3 years ago

Nice insight. I wonder what the reason for repackaging under a different group id is. Thankfully for the api there is only javax.xml.bind. So you can add that and remove the implementation.

phax commented 3 years ago

An additional insight is, that once you use JAX-WS in your implementation

      <groupId>com.sun.xml.ws</groupId>
      <artifactId>jaxws-rt</artifactId>

it also includes

  <dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
  </dependency>

and not the org.glassfish version.

But anyway, I think the problem is not directly this repository, but it's usage inside the ph-commons project, right? What project are you including that causes headaches, because for ph-commons I'm trying to remove the mandatory usage of the jaxb-impl artefact, but noted this JAX-WS Impl -> JAXB Impl dependency

T3rm1 commented 3 years ago

It is this repo as it defines the runtime as a compile dependency. As said above, this should only include the API of Jaxb. And then each project that is actually a runnable application includes its own runtime, whether it is the Glassfish runtime or for example the alternative Eclipse MOXy implementation.

phax commented 3 years ago

Yes I know, in ph-commons I changed the way how this POM is included (so that only the stuff is taken). It was used in earlier times (prior to 2.3) needed because there was not a single artifact to include. Nowadays it became easy anyway. I removed the <dependencies> for the next release to enforce usage as a BOM. That should resolve the issue.

phax commented 3 years ago

@T3rm1 have you every tried using an alternative JAXB runtime - it's just pain in the a because you need to have a "jaxb.properties" file in every package you want to have handled with a different runtime. So this is IS a purely hypothetical approach. Do you have a live, working example for me, where I could verify with a different runtime?

My knowledge is based on https://docs.oracle.com/middleware/12213/toplink/develop-document-bindings/runtime.htm#TLJAX137

T3rm1 commented 3 years ago

I don't have an example application now. But if I remember correctly, having a jaxb.properties file is just one approach to define which runtime should be used. If only one is in the classpath, it will be automatically detected. I think this is the part where it searches the classpath for the JAXBContext: https://github.com/javaee/jaxb-spec/blob/master/jaxb-api/src/main/java/javax/xml/bind/ContextFinder.java#L352

Edit: Looks like I was mistaken if this solution is correct: https://stackoverflow.com/questions/13253874/use-moxy-as-default-jaxb-implementation/13254722#13254722