mvn dependency causing NoSuchMethod errors with htmlunit - java

I have dependency:
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.10</version>
</dependency>
And run a test that includes testing a website for form submission. Works great. I package this up into my local repo mvn install and include it in another wider project.
Doing a mvn dependency:tree -Dverbose -Dincludes=net.sourceforge.htmlunit doesn't seem to reveal anything untoward
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # myproject ---
[INFO] com.myproject:myproject:war:1.0-SNAPSHOT
[INFO] \- com.myproject:myproject:mp:jar:1.0:compile
[INFO] \- net.sourceforge.htmlunit:htmlunit:jar:2.10:compile
[INFO] \- net.sourceforge.htmlunit:htmlunit-core-js:jar:2.10:compile
So I don't think any of the other deps are causing an issue. Yet if I copy/paste a test from the base project into the wider one, I always get errors:
java.lang.NoSuchMethodError: com.gargoylesoftware.htmlunit.html.HtmlPage.getElementById(Ljava/lang/String;)Lcom/gargoylesoftware/htmlunit/html/HtmlElement;
I've made sure my IDE isn't caching some dodgy library somewhere so as far as I can tell it's clean. Any ideas?
Thanks

Problem is you have this class coming from some other artifact, since you verified it is not directly coming from htmlunit with different version, it must be shaded in some other jar
for jvm to get pick up correct class please put htmlunit dependency on top of dependency so it will be first in classpath taking priority

Related

Duplicate direct dependencies in maven

I deliberately wanted to see if maven allows duplicate direct dependencies (i.e. non transitive dependencies) as it uses dependency mediation to resolve the conflicting transitive dependencies.
I wrote this is in my pom.xml
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
I was surprised to see, it is picking 4.10 version instead of 4.11. What could be reason for this ?
I will add more details that shows it violates dependency mediation principle too. Here is output of mvn dependency:tree for only standalone junit 4.10 version VS standalone junit 4.11 version:
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # PracticeMaven ---
[INFO] org.example:PracticeMaven:jar:1.0-SNAPSHOT
[INFO] \- junit:junit:jar:4.10:test
[INFO] \- org.hamcrest:hamcrest-core:jar:1.1:test
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # PracticeMaven ---
[INFO] org.example:PracticeMaven:jar:1.0-SNAPSHOT
[INFO] \- junit:junit:jar:4.11:test
[INFO] \- org.hamcrest:hamcrest-core:jar:1.3:test
If you see there is a conflict with org.hamcrest:hamcrest-core when we mention both junit in pom.xml. It should have chosen org.hamcrest:hamcrest-core:jar:1.3 as 4.11 is mentioned first. But it does not. It choses junit 4.10 and org.hamcrest:hamcrest-core:jar:1.1.
I am using latest Apache Maven 3.6.3.
Why were you surprised to see this?
It is probably always taking the last one. Avoid this if possible (the only use case I could see is to alter a dependency that was defined in a parent POM).
I'm not sure how accurate this information still is, but:
When declaring a "normal" version such as 3.8.2 for Junit, internally
this is represented as "allow any-thing, but prefer 3.8.2." This means
that when a conflict is detected, Maven is allowed to use the
conflict algorithms to choose the best version. If you specify
[3.8.2], it means that only 3.8.2 will be used andnothing else. If
somewhere else there is a dependency that specifies [3.8.1], you would
get a buildfailure telling you of the conflict. We point this out to
make you aware of the option, but use it sparingly and only when really
needed. The preferred way to resolve this is via dependencyManagement
Source: Maven: The Complete Reference, page 35
So, usually given a version without a range (using round or square brackets) is just hint what you like to use, not something Maven has to obey.

Where are servlet and JAX-RS dependencies coming from?

If I include the following J2EE dependency in my application, I have access to servlet and JAX-RS classes and interfaces:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
But where are they coming from? On Maven Central I see that javax:javaee-api:7.0 has as a dependency javax:javaee-web-api:7.0, which in turn has as dependencies javax.servlet:javax.servlet-api:3.1.0 and javax.ws.rs:javax.ws.rs-api:2.0, so on the face of it, that's the answer.
But all those dependencies are marked as optional, which means that as transitive dependencies they wouldn't show up for my project unless I explicitly include them. But yet my program compiles simply with a dependency to javax:javaee-api:7.0. Why?
Here is my dependency tree; I don't see where they are coming in:
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # temp-server ---
[INFO] com.example:test-server:war:1.0.0-SNAPSHOT
[INFO] +- com.google.code.findbugs:jsr305:jar:3.0.1:provided
[INFO] \- javax:javaee-api:jar:7.0:compile
[INFO] \- com.sun.mail:javax.mail:jar:1.5.0:compile
[INFO] \- javax.activation:activation:jar:1.1:compile
(This is all basic stuff; I don't know why I'm confused. I must be missing something obvious.)
As JAX-RS 2.0 is part of Java EE 7, the classes defining its API are directly included into the artifact javax:javaee-api:7.0 so it is enough to compile your program as long as you use standard classes only.
Here, you need to understand what is meant by <scope>provided</scope>. The javax.servlet:javax.servlet-api:3.1.0 and javax.ws.rs:javax.ws.rs-api:2.0 will be included with scope as provided when including the javaee-api dependency. What this means is that, ONLY while compiling your classes, these jar files will be used and NOT at runtime. Since the scope is provided, it expects that these 2 jars will be given by the runtime environment. To re-iterate, when any jar is included with scope as provided, it means this jar should be used for compilation, but for runtime, it expects to be provided by the runtime container.
Now to answer your question, if you consider any runtime environment container such as JBOSS, WAS, etc, they all come bundled with these jars. So at the time of compiling your classes, it will make use of the jars that come as transitive dependencies to javaee-api, but at run time it will make use of the jars that came bundled with the container instead. Hence you don't get any error.

Compilation failure on unneeded dependency of dependency

I am attempting to compile my maven project, and I am depending on another project (which is a jar file). For some reason, when I attempt to compile I get the following error which seems to be that my project can not access the required dependencies of the project I'm depending on, even though I don't use any of those dependencies.
Here is the error http://hastebin.com/pebolozuxi.sql
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /C:/Users/cneth/Desktop/Developing/PrimeMC/PrimeMobWhacker/src/main/java/org/primemc/MobWhackerManager.java:[315,34] cannot access tech.rayline.core.plugin.RedemptivePlugin
class file for tech.rayline.core.plugin.RedemptivePlugin not found
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.892 s
[INFO] Finished at: 2016-10-07T14:56:20+03:00
[INFO] Final Memory: 25M/298M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (default-compile) on project MobWhacker: Compilation failure
[ERROR] /C:/Users/cneth/Desktop/Developing/PrimeMC/PrimeMobWhacker/src/main/java/org/primemc/MobWhackerManager.java:[315,34] cannot access tech.rayline.core.plugin.RedemptivePlugin
[ERROR] class file for tech.rayline.core.plugin.RedemptivePlugin not found
I know that I can easily depend on that required dependency to solve the issue, however I don't see why that would be necessary so I wish to solve this issue without taking that route, if possible.
Thanks!
This is nothing to do with Maven. The java compiler wants that class. MobWhackerManager.java:[315,34], in fact, wants that class. The line number is right there. Your code, at line 315, references that class somehow.
Try excluding not needed transitive dependecy
https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
Your error says that the compiler misses the class tech.rayline.core.plugin.RedemptivePlugin.
So you probably need to add the jar with this class to your Maven dependencies.
From your last comment I understand that you need the jar containing RedemptivePlugin so you must keep it. In the worst case, download it manually with the right version and put it in your .m2 with the right path
previous answear
Juste to be able to help:
Have you checked the presence of your needed jar in your .m2 ?
Have you checked the full dependencies of your project to state for sure that you don't need the jar containing the class tech.rayline.core.plugin.RedemptivePlugin.
If you are sure of that, try:
<dependencies>
<dependency>
<groupId>The Project Jar That Links You To RedemptivePlugin Jar</groupId>
<artifactId>Project</artifactId>
<version>TheVersion</version>
<exclusions>
<exclusion>
<groupId>The Jar containing RedemptivePlugin</groupId>
<artifactId>theJar</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

Failed build in Jenkins: cannot resolve sqljdbc4 jar

I have started configuring Jenkins with my project. I made sure to install the sqljdbc driver in my local repository first:
$>mvn install:install-file -Dfile=sqljdbc4-4.0.jar
-DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc4 -Dversion=4.0 -Dpackaging=jar
I can see the jar has apparently been installed successfully at:
C:\Users\ me \.m2\repository\com\microsoft\sqlserver\sqljdbc4\4.0
This is what the pom relevant parts looks like:
<sqljdbc4.version>4.0</sqljdbc4.version>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>${sqljdbc4.version}</version>
</dependency>
However when I try to build the project from jenkins I get:
Executing Maven: -B -f C:\Program Files (x86)\Jenkins\jobs\Build Solutions Project\workspace\pom.xml install
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building CommonFrontPage 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: http://repo.maven.apache.org/maven2/com/microsoft/sqlserver/sqljdbc4/4.0/sqljdbc4-4.0.pom
[WARNING] The POM for com.microsoft.sqlserver:sqljdbc4:jar:4.0 is missing, no dependency information available
I'm not sure why it's not looking in my local repository first.
I also set under "configure" > "Maven Project Configuration":
Local Maven Repository Default (~/.m2/repository)
I restarted the Jenkins service too.
I am not sure how to proceed from here.
I know I could use nexus, but I don't really need it at this stage.
Maven version: 3.0.5
I managed to solve it. Since it was building correctly checking out the repository and using maven from the command line, I figured Jenkins was using a different configuration to resolve the repository, so I explicitly added:
C:/Users/me/.m2/repository
into maven's "setting.xml".
Not sure if it's the most elegant solution but at least it works now.

In Maven 2, how do I know from which dependency comes a transitive dependency?

I would like to know which dependency described in my pom.xml brings a transitive dependency in my target directory.
To be more precise, I have the library "poi-2.5.1-final-20040804.jar" in my WEB-INF/lib directory and I would like to know which dependency in my pom.xml brings that.
To add to #David Crow, here's a dependency:tree example from the Maven site:
mvn dependency:tree -Dincludes=velocity:velocity
might output
[INFO] [dependency:tree]
[INFO] org.apache.maven.plugins:maven-dependency-plugin:maven-plugin:2.0-alpha-5-SNAPSHOT
[INFO] \- org.apache.maven.doxia:doxia-site-renderer:jar:1.0-alpha-8:compile
[INFO] \- org.codehaus.plexus:plexus-velocity:jar:1.1.3:compile
[INFO] \- velocity:velocity:jar:1.4:compile
Using the Maven Dependency Plugin:
mvn dependency:tree
If you use eclipse and the m2eclipse plugin then there is a graphical version of dependency tree where you can filter by scope etc.
If you run maven with "-x" switch, it will print out plenty of diagnostics, I guess the relevant dependency path can be picked up from there.
You can have many reports by
mvn site
One of them is the dependency report.
The dependency information is also included in the Project Information/Dependencies report if you have maven generate a site for the project, using mvn site.

Categories