Wrong artifact being taken during runtime - java

Let me format the question a little bit :)
The problem is
In the runtime the specific value of enum cannot be resolved (it was introduced in 1.2 version of dependency included in project's pom.xml - this version of the library is called common-1.2.jar)
Probably caused by
Wrong dependency being taken during runtime.
Description:
In the WEB-INF/lib directory of generated war file there are three versions of common library (common-1.2.jar, common-1.1.jar, common-1.0.jar) and it looks that during runtime the older one is used. I checked it by calling values() method on my enum: there is no new - added in the 1.2 version - value there.
I executed mvn dependency:tree and there is only one common library there - common-1.2.jar. But - what can be observer - the wrong one is being used.
Question
Is there a way to find out what causes the project to use the older version during runtime?

use eclipse EE +maven plugin to trace the dependency
In eclipse EE, it has installed maven plugin. So just click the pom.xml, in editor window bottom, choose "Dependency Hierarchy". In the right side, choose commons-1.1.jar or commons-1.0.jar, in the left side "Dependency Hierarchy", you will see which jar imported the old jar.
In pom.xml, find the artifact, and add
<excludes><exclude><artifactId>commons</artifactId><version>1.0 or 1.1</version></exclude></excludes> .
Make sure in the right side, it should not exist any commons-1.0.jar or commons-1.1.jar. So your issue will be solved.

Related

Maven Eclipse plugin bug? failing to auto-add in-workspace dependency JAR to Run Configuration module-path

So here is a quick rundown of my situation:
I have two Java projects: one in Java 8 (so not modular) and one in Java 11 that is modular.
The modular/not-modular issue may not be relevant but for the sake of clarity, I've stated it.
For reference, the Java 8 is a game library I made, and the Java 11 is the game implementation I'm making.
I need to reference the Java 8 library from my Java 11 game project.
Both projects are Maven projects, and I have my dependency defined in my game's POM file.
I'm using latest version of Eclipse (2020-03 4.15.0) and Maven 3.6.3 with Java version 11.0.7 OracleJDK.
My Problem:
My understanding is that my Java 8 library project becomes an automatic module. Adding it into my Java 11 game project module-info file works (with a warning about the name being unstable, but no issue) and I can compile my game project code with no issues in Eclipse.
When I attempt to run the game, I get Module <my-library> not found, required by <my-game>. Now, since Maven is managing the dependencies, it should just work.
How can I get my game to run?
I Can Fix It Three Ways...
First I can simply manually add the library project's JAR file (in it's target folder) to the Run Configuration module-path of my game project.
Second, I can delete the library project from my workspace. This means Maven then goes and gets the JAR from the local m2 repo (it's been installed with mvn install). In this situation Maven DOES automatically add the JAR to the Run Configuration module-path correctly.
Third, I can change the version of the library project in it's POM file and like option two, this means it no longer satisfies the dependency and Maven then looks for the JAR in the local m2 repo.
But...
All three of these options seem to me like they should be unnecessary. This feels like a bug with Maven failing to add the in-workspace project dependency to the module path in the Run Configuration in Eclipse.
To be fair, it is a Maven Eclipse plugin feature that automatically detects when one of the in-workspace projects is a dependency and uses that "live" version instead of the m2 repo version. This is very handy for these situations where development on a library is happening in parallel.
But until this bug is fixed (or unless it's not a bug and I'm missing something), this caused me a ton of frustration. I've posted this in hopes of helping anyone else who may be facing the same issue.

Eclipse plugin code can't find "javax.inject.Inject" class, plugin jars now not in plugins directory

I'm trying to debug an Eclipse plugin that developed a bug around the 2019-09 timeframe. Something must have changed in the platform that causes it not to work anymore.
I can run the rcp 2018-12 distro and test it, and I verify that it works. I was able to step through the handler code.
If I run the 2019-12 distro, I can't fully compile the project, as it says "The type javax.inject.Inject cannot be resolved.". When I try to open type javax.inject.Inject in the 2018-12 distro, it finds it in "eclipse/plugins/javax.inject_1.0.0.v20091030.jar" in the distro. When I inspect that "plugins" directory, I find lots of separate plugin jars.
In the 2019-12 distro, it can't find javax.inject.Inject, and when I look in that plugins directory, I only find a single jar, the "org.eclipse.equinox.launcher" jar.
I remember this subject of the single launcher jar, but I don't know if this is a direct cause of this compile error, or what I have to do to move forward.
Update:
In response to the much appreciated answer, here's what I found:
I do find a ~/.p2 directory, and I found the javax.inject plugin in there. When I inspect the "Target Platform" settings, I see very similar information in both the 2018-12 and 2019-12 instance (plugin count varies by a very small number).
I inspected all of the MANIFEST.MF files, and none of them have a single "Import-Package" statement. I understand the advice is to add one, but I'd like to understand why I'm NOT seeing an error in 2018-12.
When I look at the "Plug-in Dependencies" list in the Project Explorer, I see "javax.inject" in the list in 2018-12, but I don't see it in 2019-12.
When I select the MANIFEST.MF file and view it in the form mode and select "Dependency Analysis" and then "Show the plug-in dependency hierarchy", I can then see that "org.eclipse.core.runtime", which is version 3.15... in 2018-12 and version 3.17... in 2019-12 has different dependencies. In particular, in 3.15, one of the dependencies is "javax.inject". In 3.17, that is not one of its dependencies.
So, I can see that a possible solution is definitely to add an "Import-Package" for "javax.inject", but can you explain why it might be that NONE of the MANIFEST.MF files have a single "Import-Package" statement as of yet?
If you are using an Eclipse installed with the Oomph installer the plugins can be in a different location (the .p2 direcory in your home directory I think). The javax.inject plugin should still be present along with all the other Eclipse plugins.
Plugins normally reference javax.inject using Import-Package in the MANIFEST.MF rather than specifying the required plugin use Require-Package so:
Import-Package: javax.inject
There haven't been any significant changes in this area between 2018-12 and 2019-12. The version of javax.inject is still exactly the same.
Check what you have configured as your Target Platform (Preferences > Plug-in Development > Target Platform) - that determines what plug-ins are available.
Update:
The reason you now need to add the Import-Package is the change made by Eclipse bug 487676 which removed the 're-export' of the javax.inject dependency from org.eclipse.core.runtime so that you now have to explicitly add it. This is also documented in the Whats New for Eclipse 2019-09 (4.13)

Issues excluding transitive dependency of project reference from eclipse class path

I have several gradle projects in my eclipse workspace. For the sake of simplicity I'm only really interested in 2 of them, let's just use A and B for this.
So the problem I'm having is that Project A has an included dependency on JBoss, which pulls in javax validation-api 1.0.0.GA, and Project B has a dependency on javax validation-api 1.1.0.Final. Since Gradle itself resolves the conflict by using the newer library first, B is happy when built by gradle. But Eclipse itself includes errors which are very distracting while editing.
The correct version of the validation-api jar ends up in B's class path but the problem is that the Gradle IDE plugin changes the project(':A') dependency to a project reference, and Eclipse seems to give the project reference precedence over the external jar. So the old jar is preferred by extension.
I tried adding { exclude module: 'validation-api' } in B's build.gradle for the dependency on A which works according to the output of 'gradle dependencies', however since Eclipse just gets as far as making it a project reference, it won't exclude the jar and the problem remains.
Also per this question I tried adding { transitive = false } and the same thing happens. I don't think even the hack posed there would work for me since the .classpath contains a single reference to the Gradle container so there's nothing to remove.
I've managed to get around this by explicitly including a reference to the correct version of the jar from my gradle cache and then moving it above the Gradle Classpath Container so that eclipse sees that version first.
My question is: Is there a better/more generic way to do this? Preferably one that I can commit to source control without breaking other people's builds or requiring them to manually modify paths or properties somewhere? There is another project with what appears to be a similar issue so something I can fix in the build.gradle file would be awesome.
Worst case scenario, I could probably switch to IntelliJ if that behaves itself better than the Eclipse-Gradle integration?
These kind of transitive dependency issues are long-standing problem with Gradle Eclipse integration (both in STS tooling and also commandline generated .classpath metadata from Gradle's Eclipse plugin. The problem is the way that Eclipse computes transitive classpaths.
Only recently we found a reasonable solution to this problem. Actually there are now two solutions, one better than the other but depending on your situation you might want to use either of them.
The first solution is a bug fix that changes the classpath order of project dependencies so that they are no longer 'preferred' over jar dependencies PR-74. To get this fix you may need to install gradle tooling from a snapshot update site because the fix went in after 3.6.3.
This solution doesn't fix the real problem (you still have the 'wrong' stuff on the classpath) but just makes it less likely to cause real problem in your projects.
The second solution is to enable use of the 'Custom Tooling API model' PR-55 introduced in STS 3.6.3. This is a bit experimental and only works for recent version of Gradle, at least 1.12 but probably better to use 2.x. It also only works for projects that have 'Dependency management' enabled (if not enabled you are using the .classpath generated by Gradle's eclipse plugin which has the same 'broken' classpath issues as the STS tooling).
The 'custom tooling model' is really the better solution in principle as it fixes the way gradle classpath get mapped to eclipse projects so that project dependencies are no longer exported and each project gets its own classpath considering dependencies conflict resolution.
To enable this go to "Window >> Preferences >> Gradle" and enable checkbox "Use Custom Tooling Model".

What is an OSGI version qualifier

I need to confirm what I suspect as I cannot find any documentation on it, so this would appear a silly question, and since I am a learner at eclipse PDE.
Initially,
I had a parent project pom of an eclipse plugin project with
<version>1.1.0-SNAPSHOT</version>
with two child projects, with both their poms referring to the parent pom as version 1.1.0-SNAPSHOT.
I was able to build the projects successfully and had a site which I use to install the plugin into eclipse.
Then, I wanted my personal temp version called 1.1.1-mine. So I modified the three poms to
1.1.1-mine
I also updated the META-INF/MANIFEST.MF and feature.xml from
0.13.0.qualifier
to
0.13.1.qualifier
However, the build encountered the following error.
[ERROR] Failed to execute goal org.eclipse.tycho:tycho-packaging-plugin:0.15.0:validate-version (default-validate-version) on project org.sonatype.m2e.subclipse: OSGi version 1.1.1.qualifier in META-INF/MANIFEST.MF does not match Maven version 1.1.1-mine in pom.xml
Does qualifier have to be a maven version keyword? Because, the build proceeded without error after I changed mine to SNAPSHOT in the poms.
If not, what did I do wrong?
What can I do to allow me to have version 1.1.1-mine?
In a nutshell, OSGi .qualifier means the same thing as -SNAPSHOT.
Since OSGi doesn't allow for more than 3 numbers in a version (+ qualifier), creating a -mine version is a bit tricky.
According to the FAQ, you can tell Tycho a string that it should be use to replace qualifier with:
mvn -DforceContextQualifier=mine
Note that this disables all the goodness you get from SNAPSHOT versions (namely that you can deploy the bundle several times).

Does anyone know if there is an eclipse plugin can point out incompatible jars in pom.xml?

Every decent sized Java EE contains tons of jar files. But what really annoys me is that you have to match different jar files version properly. For example, when using joda-time 2.2 with hibernate-entitymanager, if I choose hibernate-entitymanager 4.2.2 Final, then I will get this weird exception:
"java.lang.AbstractMethodError: org.joda.time.contrib.hibernate.PersistentDateTime.nullSafeGet(Ljava/sql/ResultSet;[Ljava/lang/String;Lorg/hibernate/engine/spi/SessionImplementor;Ljava/lang/Object;)Ljava/lang/Object;".
Then if I choose hibernate-entitymanager 3.6.8 Final, then everything works fine. I am wondering if there is a plugin can auto-detect incompatible jar files in the pom.xml editor (ex. gives warning or highlights incompatible jars) and suggest compatible versions?
I found the maven-dependency-versions-check-plugin on Github when I did a Google search. It looks well thought out, and the documentation looks pretty comprehensive. (Nice!)
Note that the documentation says you will need to build it from a source checkout ... but I actually found the plugin in Maven Central.
It is also not clear how well it will work in practice. For a start, it can only be as good as the dependency compatibility information that is included in the respective POM files.

Categories