Find in maven where a property is defined - java

I'm currently refactoring lots of pom.xml in various projects and git repo.
Sometimes, a pom in a project A will require an artifact defined in a project B in a version defined by a property :
<dependency>
<groupId>com.example</groupId>
<artifactId>artifact-from-b</artifactId>
<version>${version.from.somewhere}</version>
</dependency>
Sometimes, the version property is not obviously defined in the pom itself or its parent pom. It can be hidden in a parent's parent's parent...
I'm currently trying to find a way to resolve easily properties like ${version.from.somewhere} and find where it is defined.
Any idea of any tool that can help me (apart from eclipse, which fails for some tricky properties) ?
Thanks !

There is a related answer here Is there a way to trace origin of a property in maven pom?
That suggest using mvn help:effective-pom -Dverbose=true then you can find comments like com.example.model:2.1.0-SNAPSHOT.
I tried it and it worked for me.
In my case, the property is defined in the pom of com.example.model:2.1.0-SNAPSHOT in line 407
<dependency>
<groupId>com.example</groupId> <!-- com.example.model:2.1.0-SNAPSHOT, line 405 -->
<artifactId>model</artifactId> <!-- com.example.model:2.1.0-SNAPSHOT, line 406 -->
<version>1.0.6</version> <!-- com.example.model:2.1.0-SNAPSHOT, line 407 -->

Related

How to setup LWJGL with Maven?

Im unable to successfully add proper dependencies for LWJGL in maven project. I have copied lwjgl dependency tempalte from maven repository, added it to my pom.xml and tried to run basic application from lwjgl.org, without success.
Below you have my pom.xml file, unfortunately when I try to run my first application i get:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Failed to locate library: lwjgl.dll
I found some sollution that I need to download all jars and attach them as jar library, so I did. File > Project Structure > Librarires > added folder which store all jars for LWJGL, unfortunately this is still not working.
<dependencies>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-glfw</artifactId>
<version>3.2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.lwjgl/lwjgl-opengl -->
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengl</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>java3d</groupId>
<artifactId>vecmath</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
Please go to https://lwjgl.org/customize, select a variant ("Release" or "Early Access"), select "Mode" = "Maven", select all your needed/wanted modules and simply copy/paste the produced pom.xml snippet.
Note that the pom.xml snippet presented on the website is not a complete pom.xml. You still have to provide the surrounding <project> XML element and additional needed XML child elements.
I'm using the IntelliJ Idea IDE for this explanation.
Go to https://lwjgl.org/customize, select a version (Release, Stable, or Nightly), select "Mode" = "Maven". I personally chose "Getting Started" for the modules but you can choose base on your needs. Now press "copy too clipboard" to copy the pom.xml file.
Now open up IntelliJ and create a new project. Select Maven Project and follow the creation of the program. I called mine "maven-test". Copy and paste the script (pom.xml) from the lwjgl website that you have in your clipboard and past it before the </project>.
Also copy and paste this inside of the
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
This will prevent an error because of the default Maven compiler which is v1.5
Make a new java class under maven-test/src/main/java called Hello World and paste in the code found at https://lwjgl/guide
Finally press the Maven button on the right of the IntelliJ IDE Editor and press the refresh button that says "Re-import All Maven Projects". Right click insideHelloWorld.java and press run 'HelloWorld.main()'

SonarQube "Class Not Found" during Main AST Scan

My setup:
Sonarqube 5.1.1
Sonar-Maven Plugin 2.6 (also tried 2.7 and 3.6)
JDK 1.7.0_51
Example of the error:
16:00:54 [INFO] [23:00:54.219] Sensor JavaSquidSensor
16:00:55 [INFO] [23:00:55.030] Java Main Files AST scan...
16:00:55 [INFO] [23:00:55.030] 1532 source files to be analyzed
16:00:58 [ERROR] [23:00:57.927] Class not found: javax.annotation.Nullable
16:00:58 [ERROR] [23:00:57.928] Class not found: javax.annotation.CheckReturnValue
16:00:58 [ERROR] [23:00:58.114] Class not found: javax.annotation.Nullable
According to this stackoverflow question, javax.annotation should be part of java 1.7 and up. Furthermore, I've tried putting it in the local maven repository but that didnt help.
So where is Sonar trying to find this package? Any help?!?
Update:
I've tried modifying the sonar-maven-plugin to include a dependency on javax.annotation
I've tried putting the dependency in my maven's settings.xml
Upgrading my JDK to 1.8 has not helped.
According to http://docs.oracle.com/javase/7/docs/api/index.html?javax/annotation/package-summary.html the classes you expect are not part of JDK 7.
The classes you're looking for are part of google JSR-305 implementation that was initiated here https://code.google.com/p/jsr-305/source/browse/trunk/ri/src/main/java/javax/annotation/Nullable.java?r=24 and which moved to Findbugs:
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.0</version>
</dependency>
According to https://jcp.org/en/jsr/detail?id=305 the JSR-305 is finished, but is in dormant status and has not been added to a JDK release yet.
Hope it helps.
To avoid adding SonarQube specific dependencies to your project, define a profile like this:
<profile>
<id>sonarqube</id>
<dependencies>
<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-convert</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
</profile>
Then run your sonar analysis with a command like
mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.0.1:sonar -Psonarqube,sonarqube-dev
The sonarqube-dev profile is defined in my ~/.m2/settings.xml and it just specifies where my development environment SonarQube installation is
<profile>
<id>sonarqube-dev</id>
<properties>
<!-- no direct db connections in new sonar -->
<sonar.host.url>
http://localhost:9000/
</sonar.host.url>
</properties>
</profile>
What is achieved by all this?
sonarqube analysis specific dependencies don't pollute the project unnecessarily
no sonarqube maven plugin defined in pom.xml. Each developer and Jenkins can use whatever sonar plugin and server installation they wish
This is more an addendum to the latest answer:
I see similar problems and adding the google findbugs dependency to the project dependencies helps. Similar problems occured with joda convert like
[ERROR] [20:44:25.247] Class not found: org.joda.convert.ToString
Hence I also added
`<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-convert</artifactId>
<version>1.8.1</version>
<scope>provided</scope>
</dependency>`
But note, that I set the scope to provided to prevent these new dependencies to be added to a resulting war file.
However, I still wonder why these errors occur since none of the analyzed classes seem to use these annotations?

Weld OSGi + Apache Felix = can't find packages

I use Apache Felix and weld-osgi for a Java SE application. The problem is that in injected bean I use #ApplicationScoped from package javax.enterprise.context.ApplicationScoped. But there is no such package in weld-osgi-bundle-2.1.2.Final.
This package exist in weld-se but it's not in the OSGi bundle. How can I solve this problem?
I would try running the following dependency as separate bundle:
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.1-20130918</version>
</dependency>
(Maven Central link)
Be careful, you need version 1.1-20130918. Version 1.1 does not have OSGi headers in the MANIFEST.MF. You can unzip the jar and check the META-INF/MANIFEST.MF file for OSGi headers like Bundle-ManifestVersion and Bundle-SymbolicName. You can also check here the required packages of that bundle, it's in the Import-Packages header.
How to figure out
Check the dependencies of weld-osgi-bundle on Maven Central (or in its pom.xml). It contains the following:
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-api</artifactId>
</dependency>
This weld-api refers to the cdi-api above which contains the missing annotation:
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
</dependency>
Another way is pressing F3 (Open Declaration) in Eclipse while the cursor in the ApplicationScoped annotation then in the Project Explorer View enable the Link with Editor and it will show that ApplicationScoped.class is inside the cdi-api-1.1.jar.
Finding OSGi version of another jars
You probably need more bundles than this one (transitive dependencies or it was only the first one which stopped the installation).
Not all well-known jar has OSGi headers, like the following one:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
In that case search for the group id on Maven Central. Two results which contain the javax.inject package and have OSGi headers:
org.glassfish.hk2.external
org.apache.servicemix.bundles
If you can't find anything you can convert any jar to OSGi bundle by hand. Actually, you can do this with the weld-se.jar but installing dependencies separately looks cleaner.

Maven plugin builds but can't execute due to java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

I am using the maven-jspc-plugin in my pom.xml.
When i try to execute the jsp-compile goal (which executes the plugin) I get:
Caused by: java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at org.apache.juli.logging.Slf4jLog.<init>(Slf4jLog.java:29)
at org.apache.juli.logging.LogFactory.getLog(LogFactory.java:54)
at org.apache.juli.logging.LogFactory.getLog(LogFactory.java:35)
at org.apache.sling.scripting.jsp.jasper.compiler.OriginalTldLocationsCache.<init>(OriginalTldLocationsCache.java:81)
at org.apache.sling.maven.jspc.JspcMojo.initServletContext(JspcMojo.java:426)
I've tried downloading the (open) source for the maven-jspc-plugin and i am able to easily "mvn install" -- I don't get any build issues, however when i use that build in my project pom it still crashes and tells me it can't find LoggerFactory.
I've logged an issue with the Apache Sling project but am not making much headway.
https://issues.apache.org/jira/browse/SLING-2350
This link includes some more troubleshooting info as well as a simple maven project that uses the maven plugin. downloading the jspc-test.zip and "mvn install"ing will result in the error I've mentioned.
Also, i took a peak at the org.apache.juli pom.xml and it doesnt appear to list any dependencies at all.
Any thoughts on how to resolve would be appreciated.
Thanks!
Plugin dependencies are supplied in a different part of the POM:
<project>
<dependencies>
<!-- dependencies defined here don't get included for plugins -->
...
</dependencies>
<build>
<plugins>
<plugin>
.... jspc plugin section ....
<dependencies>
<dependency>
<!-- Try adding slf4j here --->
Though it does sounds like their POM is invalid if it doesn't already specify slf4j.

Apache Maven: What is the difference between Inheritance, Aggregation, and Dependencies?

I'm new to Maven, and I'm trying to understand why my company's modules are organized into 'module groups', but also each sub-module declares its parent explicitly. I don't quite understand what the POM Reference is trying to say about the difference between inheritance and aggregation.
For example, a parent module:
<groupId>example.group</groupId>
<artifactId>util</artifactId>
<packaging>pom</packaging>
<name>Util Parent</name>
<modules>
<module>util_client</module>
<module>util_core</module>
<module>util_server</module>
</modules>
And one of its children:
<parent>
<artifactId>util</artifactId>
<groupId>example.group</groupId>
<version>trunk-SNAPSHOT</version>
</parent>
<groupId>example.group.util</groupId>
<artifactId>util_core</artifactId>
<packaging>jar</packaging>
<name>Util Core</name>
Why declare it both ways? Is it redundant? To make things even more confusing, some of the util submodules depend upon eachother:
<groupId>example.group.util</groupId>
<artifactId>util_client</artifactId>
<packaging>jar</packaging>
<name>Util Client</name>
<dependencies>
<dependency>
<groupId>example.group.util</groupId>
<artifactId>util_core</artifactId>
</dependency>
</dependencies>
Sorry if this is a doozy of a question, but wow this is confusing! Thanks for your help.
When you define sub-modules, you can build and release them all at once from the top level.
When you use inheritance in the second example, you can use definitions from the parent POM defined once, (Like which versions of software to use)
In the last example, when one module needs resources from another module, you can add it as a dependency and it will download and include it in the build path automatically.

Categories