简体   繁体   中英

OSGi: javax.annotation conflict: Java SE vs Java EE

In a Java SE OSGi (Apache Felix) environment, I'm trying to integrate CDI using PAX CDI and Weld 2.2.6.Final.

I'm currently getting the following error:

ERROR: Bundle org.jboss.weld.osgi-bundle [45] Error starting file:///someDir/org/jboss/weld/weld-osgi-bundle/2.2.6.Final/weld-osgi-bundle-2.2.6.Final.jar (org.osgi.framework.BundleException: Uses constraint violation. Unable to resolve bundle revision org.jboss.weld.osgi-bundle [45.0] because it is exposed to package 'javax.annotation' from bundle revisions org.jboss.spec.javax.annotation.jboss-annotations-api_1.2_spec [39.0] and org.apache.felix.framework [0] via two dependency chains.

Chain 1:
  org.jboss.weld.osgi-bundle [45.0]
    import: (&(osgi.wiring.package=javax.annotation)(version>=1.1.0))
     |
    export: osgi.wiring.package=javax.annotation
  org.jboss.spec.javax.annotation.jboss-annotations-api_1.2_spec [39.0]

Chain 2:
  org.jboss.weld.osgi-bundle [45.0]
    import: (&(osgi.wiring.package=com.google.common.util.concurrent)(version>=13.0.0))
     |
    export: osgi.wiring.package=com.google.common.util.concurrent; uses:=javax.annotation
  com.google.guava [1.0]
    import: (osgi.wiring.package=javax.annotation)
     |
    export: osgi.wiring.package=javax.annotation
  org.apache.felix.framework [0])

I think it's because Java SE (v8) already defines a package "javax.annotation" but Java EE (v7) specifies the same package with more annotations.

"javax.annotation", however, is exported already as a system package by the system bundle (org.apache.felix:org.apache.felix.framework:jar:4.2.1).

What is the correct way in this case to make OSGi pick the one from Java EE instead?

Edit

  1. only add the system packages that are truly necessary from the JDK

    This is not possible in this case as I'm writing a framework, not an application ( Drombler FX ).

  2. Exclude javax.annotations from the org.osgi.framework.system.packages system property in default.properties

    Actually, I've tried that already as I have a copy of default.properties in the framework anyway. It worked, but it seems more like a hack and increases the maintenance work when I need to upgrade this file. Also if ever the Maven Bundle Plugin checks the exported packages at compile time (which I would welcome), the people would have to start adding additional dependencies to their project when they want to use javax.annotations as that package would be exported by the system packages anymore. I was hoping to find a better solution.

  3. Use the endorsed mechansim

    This looked like the cleanest solution so far, but I still hoped I could avoid that, since it increases the application packaging complexity.

Now, I just checked the Java SE 8 documentation and was surprised that JSR 250 is not listed as an endorsed technology anymore!??? It was listed as an endorsed technology in Java SE 7. Did they really remove the endorsed support for JSR 250 in Java SE 8 or is the documentation incorrect?

Java SE 8: https://docs.oracle.com/javase/8/docs/technotes/guides/standards/

Java SE 7: https://docs.oracle.com/javase/7/docs/technotes/guides/standards/

If it is still supported in Java SE 8, what do you think about this approach?

Any other approaches?

One of the big issues of Java is that more and more packages are put into the JDK that should be standalone project with its own versioning lifecycle. This does not cause a problem in monoholitic projects, but makes a pain within OSGi.

That is why we only add the system packages that are truly necessary from the JDK and we get everything from bundles. You will be surprised how much packages you actually need from the JDK.

A quick fix could be if there was an org.osgi.framework.system.packages.exclude system property but sadly it does not exist.

A slow solution is if you specify the org.osgi.framework.system.packages with no packages and you find one-by-one which package you actually need. You will be surprised how less packages you will need.

A quicker but more dirty solution is if you get into felix.jar, find default.properties and copy out the content of the org.osgi.framework.system.packages system property with the exclusion of javax.annotation.* classes. By the time you will realize that you will have the same issue with javax.transaction.* packages and as an outcome, you will need to get javax.sql.* packages from a bundle...

Sadly in felix you must list the osgi-core packages as well in the list of system packages. With Equinox, those packages do not have to be listed (which is good in my opinion as osgi-core packages should not be part of system packages configuration).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM