Maven: Reverse-POM from Source - java

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

The package com.fasterxml.jackson.databind is not accessible Java (268436910)

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?

Maven Dependencies .jar non existing library

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?

AEM, Maven : duplicated package name

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>

Maven: how to override 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>

Maven - moved code to new artifact; transitive dependencies issue

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.

Categories