Java 10: Replacement for java.xml.ws conflict - java

I have to use java.xml.ws* components in my project but because it's deprecated and will be removed soon I want to use replacement for these components. So I added this dependency to my project's pom file:
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-ri</artifactId>
<version>2.3.0</version>
<type>pom</type>
</dependency>
This is my module configuration:
module x.y.z {
requires kotlin.stdlib;
requires spring.boot;
requires spring.boot.autoconfigure;
requires spring.context;
requires cxf.core;
requires cxf.rt.frontend.jaxws;
requires java.xml.ws;
}
But there is an error:
What does it mean and how to fix it so I can use my dependency above instead of java.xml.ws from jdk?

Just use Java 11 :) There is no javax.xml.ws module there, so no conflict.
As for Java 10, the easiest workaround is to change the scope of jaxws-ri to runtime:
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-ri</artifactId>
<version>2.3.0</version>
<scope>runtime</scope>
</dependency>

By adding requires java.xml.ws you tell the module system that you depend in the deprecated Java EE module java.xml.ws, which it will then resolve and make available. At the same time there seems to be a module of the same name on the module path. (Maybe a JAR pulled in by jaxws-ri?)
Although, come to think of it, I would have expected a compiler message complaining of duplicate modules... It looks like the error (is it compiler or runtime?) comes from an IDE. What happens if you run the build with Maven?
Anyways, if you are willing to start with Java 11, you could give that a try. The Java EE modules are removed, so there is no chance of a platform module interfering. I'm not sure whether it is possible to add a java.* module on the module path, though.
If it is not or you prefer to stick to Java 10, you should take a look at upgreadable modules and the --upgrade-module-path option. That way you can use the JARs that provide the JAX WS API to replace the platform module.

Related

How to add maven dependencies of json to modules in >= Java 9

in java 8 projects you simply add the following dependencys in maven
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1</version>
</dependency>
Using OpenJDK, Eclipse 2018-12
and maven module, it results in getting a error in the module-info.java:
The package javax.json.stream is accessible from more than one module:
java.json, org.glassfish.java.json
So in both dependency projects there is a package called javax.json.stream and due to jigsaw module system this is not allowed anymore?
How to fix this?
EDIT:
I updated the maven dependency to 1.1.4 and put them on the classpath.
The javax.json-api has a module-info.java file and is working fine, eclipse shows no more errors.
But now the packages of the implementation javax.json (org.glassfish) are not found, resulting in a ClassNotFoundException: org.glassfish.json.JsonProviderImpl
What more can I do?
EDIT:
Its working now, i forgot to generate a module-info.java in this project.
So in both dependency projects there is a package called
javax.json.stream and due to jigsaw module system this is not allowed
anymore?
This is still allowed, but with both those dependencies getting resolved on the classpath instead of modulepath i.e. in the unnamed module.
Another alternative to fix this while you create your library as modular is to make sure to fix the downstream libraries exporting the same package which would require a bottom-up migration and you might have to wait for them to fix it in their latest update(or check if one is already out) and then to rely on them.

Include a library while programming & compiling, but exclude from build, in NetBeans Maven-based project

In NetBeans 8, in a Maven-based project, how does one use a jar while programming but omit from build?
I need to access some specific classes in a specific JDBC driver in my Vaadin web app. But in web apps, we normally do not bundle JDBC drivers within our build (the .war file). Instead, the JDBC drivers belong in a folder controlled by the Servlet container (the runtime environment).
So, I need the JDBC driver (a jar file) to be on the classpath while I am editing my code and compiling. But that jar file must be omitted from the build.
exclusions Tag
I tried adding the exclusions and exclusion tags to my dependency element. But this did not work – The postgresql-9.4-1201.jdbc41.jar appeared in WEB-INF/lib folder.
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1201-jdbc41</version>
<exclusions>
<exclusion>
<groupId>org.postgresql</groupId> Exclude from build
<artifactId>postgresql</artifactId>
</exclusion>
</exclusions>
</dependency>
New Profile?
This Answer by ZNK - M on the Question, Setting custom runtime classpath for a maven project in netbeans, may be what I need.
But creating a new project profile seems like overkill what seems like small little task to me. And, I always want to exclude this jar from my build output, not just when testing or in other limited scenarios.
You should add a new profile run-with-netbeans in your pom that declares the additional dependencies (use the provided scope to not include them in the release).
Then you'll have to add the new profile to your IDE to run the pom with the -P run-with-netbeans option in the command line.
But I am familiar only with the basics of editing a POM file. If that approach is the way to go, it would be helpful if someone could expand on the details and steps needed.
<scope>provided</scope>
Use <scope> tag in POM file, with a value of provided.
Excerpt from the Dependency Scope section of the page, Introduction to the Dependency Mechanism :
compileThis is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.
providedThis is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.
runtime[…]
test[…]
system[…]
import[…]
Like this:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1201-jdbc41</version>
<scope>provided</scope>
</dependency>
Use the provided scope instead of the default compile scope for this dependency. That's exactly what it's for.
<dependency>
<scope>provided</scope>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
</dependency>

Why do I need adding artifact JSR305 to use Guava 14+?

While looking for informations on stackoverflow, I have seen a question similar to mine, but with no real answer here.
I need migrating my maven project from guava 11.0.2 to guava 14 or higher (I need RangeSet). I updated my maven pom with the dependency:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>14.0</version>
</dependency>
I then run the maven build, and got this error:
[ERROR] xxx.java: cannot find symbol
[ERROR] symbol : class Nonnull
[ERROR] location: package javax.annotation
I took a look closer, and this annotations is provided with JSR305, on which depends guava 11.0.2, as mvn repository reports it.
What I find strange is that guava 14 also depends on JSR305 as mvn repository reports.
If I add the JSR dependency to my pom, then the compilation just runs fine:
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>1.3.9</version>
<scope>provided</scope>
</dependency>
But why would I have to add this dependency to my pom if guava already depends on it ? This looks more to a workaround than to a solution, and I would prefer to understand and make things clean.
Thanks for participating.
The reason that you need to add it as a dependency is because Guava 14 defines the dependency in their pom as follows:
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>1.3.9</version>
<scope>provided</scope>
</dependency>
The important part for your problem is the <scope>provided</scope> line.
From the maven website they state the following with regards to provided dependencies:
provided:
This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.
So basically because Guava have set this as a provided dependency they expect whoever is consuming Guava to provide this dependency which is exactly what you have had to do.
In Guava 11.0.2 it was a normal compile dependency, hence you didn't have to provide it in your own project.
The change was made in Guava 13. From the release notes:
Made findbugs a provided dependency to avert dep conflicts when using findbugs 2.0. The side-effect of this change is that projects which relied upon Guava to grant access to the JSR-305 annotations "for free" will break unless they provide their own direct dependency on that jar (or an equivalent). Projects should always have been directly depending on JSR-305 (per maven best-practice), but this change makes that should into a must.

Maven Dependency Conflict

A maven project consisting of some modules. One of my module is using guava dependency of google version 11.0.2. Now i am integrating another module in my project which is also using guava but version 14.
So i want that new module uses guava version 14 but remaining project use guava version 11.0.2. I have tried adding <exclusion></exclusion> of guava to the new module but it didn't work.
Any tips to solve this.
Update: #Guillaume Darmont's Answer solves the problem for different modules. but now my problem is, the new modules has 2 dependency one of the them is using guava 11.0.2 and other is using 14.0. how to manage this. can we specify separately in the pom of the module that which version of the guava it should use.?
As I understand your question, you may add a <dependencyManagement> for guava in your new module pom.xml :
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>14.0.1</version>
</dependency>
</dependencies>
</dependencyManagement>
mvn dependency:tree command will help to determine which module is bringing the Guava 14 jar file.
Firstly try mvn dependency tree and check the output it is possible that 11.0.2 has been transitively referenced from more than one of your projects dependencies and you will need to add exclusion to all the dependencies directly / indirectly pulling down the specific guava version you are trying to exclude.
Secondly resolving this conflict may not be straight forward. Looking at version number transition (11 to 14) sounds to me like a major transition, and you may have better chances keeping the 14 version and excluding the 11 something.
If the version change is not compatible with your application, you have pretty much no option but to use something like OSGi to ensure you can run different versions of same library in the project.

Add all artifacts from JBoss Maven repo to Maven project in Eclipse

I'm using JBoss EAP 6.0.1 (NOT JBoss AS 7.1.1 or 7.1.3!) and I'm just starting with a Maven project.
In normal Eclipse projects I set the target runtime of my project to the JBoss EAP server runtime and then all its libraries are available to my project. Available here means I can use e.g. ctrl-t to find a class in any of those libraries, and when I attach the source I can step into them when debugging.
How would I do this using Maven (m2e)?
I've found the Maven repository for JBoss EAP 6.0.1 at http://maven.repository.redhat.com/techpreview/eap6/6.0.1/
Do I need to add some root dependency (representing JBoss EAP itself) to my project, and if so, what would this dependency be?
I found a very similar question here: Adding JBoss AS 7 modules on Eclipse using Maven or JBoss Tools
But the accepted answer only says: "Take a look at these links", which doesn't tell me how to exactly do this (and it's for AS 7.1.1 not for EAP 6.0.1).
UPDATE
I wasn't entirely clear about the question. I'm not looking for a mere reference to the Java EE APIs. I know how to do that, as it's simply:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>1.6</version>
<scope>provided</scope>
</dependency>
I'm also NOT looking for any vendor versions of that spec jar. I'm absolutely NOT looking for the following one either:
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
</dependency>
What I'm looking for is having all implementation libs available in the project. The JBoss AS 6 server runtime does this by default, and with the JBoss AS 7/EAP 6 server runtime you can do this by going to Server -> Runtime Environments -> Default Classpath (you can enter individual paths there, or just add the /modules rootpath to have everything at one)
I'm looking for the equivalent of this in a Maven project.
I'M NOT LOOKING FOR SPEC JARS!!!!
As I need to step through the ACTUAL IMPLEMENTATION jars of the target server, I REALLY need the ACTUAL IMPLEMENTATION jars. I KNOW I can't deploy these, and nor do I intend to deploy them. They need to be present in my IDE, so there's source code that matches what's in the target JVM and I can use CTRL-SHIFT-T to lookup IMPLEMENTATION classes and CTRL-CLICK to navigate into them, analyse call hierarchies, etc.
AGAIN: I'M NOT LOOKING FOR SPEC JARS!!!!
You can import the dependencies manually into your repository. I did it into ours (artifactory) and it's working.
See: https://access.redhat.com/site/documentation/en-US/JBoss_Enterprise_Application_Platform/6/html/Development_Guide/Install_the_JBoss_Enterprise_Application_Platform_6_Maven_Repository_Locally.html
I found a surprisingly simple solution my self: even though libs are managed via Maven, and a target runtime is disabled by default, you can still explicitly select a target runtime.
The libraries this target runtime puts on the classpath will now also be put on the classpath for the Maven project, in addition to those Maven already puts there. You can (manually) attach the source code to those libraries.
Once you're doing with debugging and stepping through the internals of your AS, you can simply remove the target runtime again.
An answer that tells how to do this purely via Maven and for JBoss EAP 6.0.1 (not JBoss AS 7.1.1 or 7.1.3) would still be welcome, so I won't accept my own answer ;)
There is a nice explanation of the JBoss Maven repositories at: https://community.jboss.org/wiki/MavenRepository
I would guess the repository you need to use is: https://repository.jboss.org/nexus/content/groups/public-jboss/
it should contain all JBoss artifacts you're looking for.
Maybee the groupId/artifactId is not correct. There is a search feature for the repositories at: https://repository.jboss.org/nexus/index.html#welcome
I would recommend to not include the impl jars as you cannot deploy them anyway. So the spec jars should be ok:
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
</dependency>
see: http://www.andygibson.net/blog/quickbyte/jboss-java-ee-6-spec-dependency-in-maven/
The gav for the JBoss server seem to change a lot. JBoss 7 can be found at:
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-ee</artifactId>
<version>7.1.3.Final</version>
</dependency>
Take a look here:
JBoss Enterprise Application Platform Component Details
And in my pom.xml I'm using this to get dependencies from Jboss EAP 6.0.1
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<type>pom</type>
<scope>provided</scope>
<version>3.0.2.Final</version>
</dependency>
You can use Nexus or Git or Overlord to manage project artifacts in order to create a proxy virtual dependency, if i am not mistaken.
Runtime artifacts can be used:
<!-- https://mvnrepository.com/artifact/org.jboss.bom/eap-runtime-artifacts -->
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>eap-runtime-artifacts</artifactId>
<version>7.1.0.GA</version>
<type>pom</type>
<scope>import</scope>
</dependency>
See https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.1/html/development_guide/using_maven_with_eap#manage_project_dependencies

Categories

Resources