Suppose I have a fat-jar including all dependencies, probably built with maven-assembly-plugin. Is there some clever way to "reverse" the status-quo without having the original POM?
For example automagically generate a
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.0.2</version>
</dependency>
just by having a package com.fasterxml.jackson.core inside my src folder
Related
I have recently explored handling JSON data with the org.json library and all went well.
Now I started a bigger Maven project, for which I intend to use the Jackson libraries in stead.
Sadly, it does not seem to work for me. I wanted to try out the ObjectMapper class, that VScode autocompleted for me, which also automatically adds the required import:
import com.fasterxml.jackson.databind.ObjectMapper;
However, I also immediately get an error on that line:
"The type com.fasterxml.jackson.databind.ObjectMapper is not accessible Java (16778666)"
I have added the necessary dependencies to my pom.xml file like so:
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>13</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.14.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.14.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.0</version>
</dependency>
</dependencies>
Am I missing something? Are there any other steps that I should have taken?
The only dependency needed for ObjectMapper is
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.0</version>
</dependency>
This error occurs, because Jackson library is not included in your project's classpath. Probably your project is using the Java Platform Module System (JPMS); then log would also contain:
... declared in the "unnamed module" ... module does not read it.
If this is the case, add a requires directive to module-info.java file to specify that this module requires the jackson-databind library:
module correct.module.name {
requires com.fasterxml.jackson.databind;
}
After adding this requires directive recompile the project again.
This is not a Maven problem. You probably have created a package-info.java for your project and so all your dependencies ended up on the module path but your package-info.java is missing the corresponding declarations.
You have to add a line like this:
requires com.fasterxml.jackson.databind;
See also: How to fix 'Package is declared in module, but module does not read it' error in IntelliJ JavaFX?
The container 'Maven Dependencies' references non existing library 'C:\.m2\repository\com\portal\pcm\12.0.3\pcm-12.0.3.jar'
If i check the folder there are files that have the same name as the jar but end on jar.lastUpdated.
I tried maven clean and maven update which did not work. I delete the *.jar.lastUpdated in m2, but did not work too.
The line in my pom.xml is:
Missing artifact com.portal:pcm:jar:12.0.3
Missing artifact com.portal:pcmext:jar:12.0.3
Missing artifact com.portal:pcmext:jar:12.0.3
This block is the one with the marker where it states the artifact is missing.
<dependency>
<groupId>com.portal</groupId>
<artifactId>pcm</artifactId>
<version>12.0.3</version>
</dependency>
<dependency>
<groupId>com.portal</groupId>
<artifactId>pcmext</artifactId>
<version>12.0.3</version>
</dependency>
<dependency>
<groupId>com.portal</groupId>
<artifactId>pfc</artifactId>
<version>12.0.3</version>
</dependency>
I tried to use a version suggested by mvnrepository.com/artifact/com.portal.pcm/pcm/7.5, but didnt work too.
<dependency>
<groupId>com.portal.pcm</groupId>
<artifactId>pcm</artifactId>
<version>7.5</version>
</dependency>
<dependency>
<groupId>com.portal.pcm</groupId>
<artifactId>pcmext</artifactId>
<version>7.5</version>
</dependency>
<dependency>
<groupId>com.portal.pcm</groupId>
<artifactId>pfc</artifactId>
<version>7.5</version>
</dependency>
i guess dependency configuration is incorrect, but which is correct?
I want to add "fop-core" dependency.
My project was added "uber-jar" dependency already.
The uber-jar dependency has org.apache.fop.apps.FopFactory.java file.
But, doesn't have org.apache.fop.apps.FopFactoryBuilder.java file.
The fop-core dependency has both FopFactory.java and FopFactoryBuilder.java files.
Thus, my program loads FopFactory.java in "uber-jar" instead of "fop-core".
How can I resolve this duplication??
Can I remove "FopFactory.java" file in "uber-jar" dependency?
OR
Can I force load "FopFactory.java" file in "fop-core" dependency?
uber-jar
<groupId>com.adobe.aem</groupId>
<artifactId>uber-jar</artifactId>
<classifier>apis</classifier>
</dependency>
fop-core
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop-core</artifactId>
<version>2.5</version>
</dependency>
Make sure that the fop-core dependency is coming first in your pom. That should do the trick.
HTH, OliG
Echoing Oliver Gebert response, I did that a few months ago for Apache POI, in the main pom.xml, I put it as the first dependency:
<dependencyManagement>
<dependencies>
<!-- Apache POI (First in order to avoid conflict with the version from the UberJar) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.11</version>
</dependency>
My situation is a bit strange:
Dependency with artifact id: yyy in the pom (see below) has dependency:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>2.5</version>
</dependency>
So the problem is I need to use the 3.1.0 version in the current module because it has extra functionality:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
I have tried the exclusions tag and dependencymanagement tag explained in the example on the page: Maven: how to override the dependency added by a library
It does not work. I have also read and tried the 3 examples in this article: https://spring.io/blog/2016/04/13/overriding-dependency-versions-with-spring-boot
It also did not work. So what I did was to re-order my pom dependencies so that the 3.1.0 goes before the one with artifact yyy and I was happy it worked I built successfully a clean install. My happiness was short lived because after a clean install the pom re-ordered itself and the 3.1.0 was automatically re-ordered back below the yyy. Which means the next build will use 2.5 again and fail.
My pom structure snippet is as below:
<dependencies>
<dependency>
<groupId>xxxx.xxx.xxxx</groupId>
<artifactId>yyy</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependencies>
My happiness was short lived because after a clean install the pom
re-ordered itself and the 3.1.0 was automatically re-ordered back
below the yyy. Which means the next build will use 2.5 again and fail.
Note that the javax.servlet:javax.servlet-api has to be included in a WAR but only in a standalone JAR that includes and bootstraps a servlet container.
If you build a standard WAR you have to use the dependency provided by the server. So the dependency should be declared with the provided scope.
I have tried the exclusions tag and dependencymanagement tag explained
in the example on the page: Maven: how to override the dependency
added by a library
dependencyManagement will be helpless here as the issue is related to a dependency you include outside the dependencyManagement element.
But using the exclusions option in the dependency declaration is the right way. It should exclude the 2.5 version of the javax.servlet-api artifact if used in this way :
<dependencies>
<dependency>
<groupId>xxxx.xxx.xxxx</groupId>
<artifactId>yyy</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<artifactId>javax.servlet</artifactId>
<groupId>javax.servlet-api</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
If the problem persists it means that the dependency is probably pulled by another dependency.
Some hints that generally help to discover that :
check that you don't use WAR overlay feature. But not likely here as you retrieve only 1 version of the dependency
use mvn dependency:tree on the WAR project to inspect all pulled dependencies.
To ease the readable you can also filter in this way :
mvn dependency:tree -Dincludes=javax.javax.servlet-api
The solution below has ignored the version 2.5 and so it is working. However i don't know what it means. Does it remove other dependencies? Please interpret what the asterix in groupId and artifactId mean in simple english. I want to know the risks because i am using a multi module system where there to many nested dependencies in other dependencies. I will continue to research as of now but if anyone can explain please do. Thanks
<dependencies>
<dependency>
<groupId>xxxx.xxx.xxxx</groupId>
<artifactId>yyy</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId> // this works or
<groupId>*</groupId> // this works
<artifactId>*</artifactId> // this part was a mandatory *
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
Here is my situation:
I created a new artifact in a library called 'web-ng-framework', and moved code into it from an old artifact in the library, 'web'
I deleted the 'web' artifact
And here is the problem:
ProjectA uses an older version of the library, and so it has a compile dependency on 'web'
ProjectB depends on ProjectA
ProjectB uses the latest version of the library, so when ProjectB is built, it contains both the 'web' and 'web-ng-framework' libraries, causing a possible conflict
Does anyone know how I can solve this? Thanks!
EDIT:
Would doing 'relocation' of 'web' to 'web-ng-framework' maybe work better? In ProjectA, I could include a dependency on 'web' so that Maven would see that what it really needs is 'web-ng-framework'. Would that work?
When including ProjectA in ProjectB exclude web. Like this
<dependency>
<groupId>your.group</groupId>
<artifactId>projectA</artifactId>
<exclusions>
<exclusion>
<groupId>your.group</groupId>
<artifactId>web</artifactId>
</exclusion>
</exclusions>
</dependency>
A classic solution to this problem is the 'Version 99' hack.
To do this, use the following in your root pom:
<dependencyManagement>
<dependency>
<groupId>your.group</groupId>
<artifactId>web</artifactId>
<version>99.0-does-not-exist</version>
</dependency>
</dependencyManagement>
Then put an empty web-99.0-does-not-exist.pom and web-99.0-does-not-exist.jar in your repository.
This ensures that every project that inherits from this root pom will not get the old version of the web.jar anymore.
I suggest that you use optional dependencies
This can be acheived by making web depencency optional in projectA.
<project>
<groupId>some.group</groupId>
<artifactId>projectA</artifactId>
...
<dependencies>
<!-- declare the dependency to be set as optional -->
<dependency>
<groupId>some.group</groupId>
<artifactId>web</artifactId>
<version>1.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>
When declaring some other project that depends on projectA the web dependency will not be included.
<project>
<groupId>some.group</groupId>
<artifactId>projectB</artifactId>
...
<dependencies>
<dependency>
<groupId>some.group</groupId>
<artifactId>projectA</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>some.group</groupId>
<artifactId>web-ng-framework</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
Now projectB will only have a dependency on projectA and web-ng-framework, not web.