Getting property from pom.xml within java - java

I have a maven project, and in the pom.xml I set properties as such:
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>myArtifact</artifactId>
<name>SomeProject</name>
<packaging>jar</packaging>
<properties>
<some-system-property>1.9.9</some-system-property>
</properties>
<...>
</project>
I want to pull the some-system-property value from within the java code, similar to
String someSystemPropery = System.getProperty("some-system-property");
But, this always returns null. Looking over StackOverflow, most of the answers seem to revolve around enhanced maven plugins which modify the code - something that's a nonstarter in my environment.
Is there a way to just get a property value from a pom.xml within the codebase? Alternatively, can one get the version of a dependency as described in the pom.xml (the 1.9.9 value below):
<dependencies>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.9</version>
</dependency>
</dependencies>
from code? Either one would solve my needs

Those are Maven properties that apply during the build, not runtime system properties. One typical approach is to use Maven resource filtering to write the value into a properties file in the target directory.

Maven properties and not system properties.
Generally you should set the system property for a maven plugin that is triggering the execution:
surefire for unit tests,
exec for execution,
jetty or similar for starting a web container
There is also properties maven plugin than can set properties:
http://mojo.codehaus.org/properties-maven-plugin/set-system-properties-mojo.html

Property values are accessible anywhere within a POM by using the notation ${X}, where X is the property, not outside. All properties accessible via java.lang.System.getProperties() are available as POM properties, such as ${java.home}, but not the other way around. So for your java code, it will need to scan the pom.xml as a xml parsing use case, but not sure why you want to do it.

Related

Programmatically retrieve Maven Dependencies

Pls are there any Java libraries that can retrieve Maven dependencies from a POM file? Anything that does not require retrieving out put of a mvn command. Thanks
Well, you should parse the pom.xml with any xml parser of your choice.
Then construct the link to maven central repository by the following algorithm:
1. Each package in group id is translated to a folder:
Example:
<groupId>org.foo.bar</groupId> ==> org/foo/bar
Artifact name is also a folder and append it to the group id:
Example:
<artifactId>some-artifact</artifactId> ==> org/foo/bar/some-artifact
Version also becomes folder:
Example:
<version>1.2.3</version> ==> org/foo/bar/some-artifact/1.2.3
Now construct the jar name as "articatId-version.jar" and append it to the link.
Prepend the repository and you'll get a full-working path.
Here is a real working example:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
Gets translated to:
https://repo1.maven.org/maven2/org/springframework/boot/spring-boot/2.2.4.RELEASE/spring-boot-2.2.4.RELEASE.jar
As an alternative if you want some library that can work with dependencies don't want to call maven, take a look at Apache Ivy
Thanks.
I used the MavenProject library. Pretty straight forward.
I also used MavenXppReader to get the model that I passed to MavenProject(). The rest was a matter of calling the right methods.

How can I update a pom.xml property in terminal in spring project?

Say, there is a property customProp in the pom.xml in my spring project.
2.4.snap
When I run my project, I can update its value like below
mvn clean install -DcustomProp=newValue
It's working well. It updates the value of customProp with newValue.
But I want to concat newValue with the previous value of customProp. So that the value of customProp will be 2.4.snapnewValue.
How can I do that?
Further, is it possible to replace snap with newValue so that the value of customProp will be 2.4.newValue.
<properties>
<customProp>snap</customProp>
</properties>
<version>2.4.${customProp}</version>
Would this be possible in your situation? Of course, use the correct tag where I'm using <version>.
The best way to approach this might be more like:
<properties>
<customPropPrefix>2.4.</customPropPrefix>
<customProp>snap</customProp>
</properties>
<version>${customPropPrefix}${customProp}</version>
Now you can specify both -DcustomPropPrefix=2.4. and -DcustomProp=newValue.
Rather than build and clean your maven project forcefully it will sure update your maven projectenter image description here

Disable Sonar duplications on Entity, DTO packages

Is there any way to disable certain metrics from selected packages in Sonar? I use Sonar to analyze my project and in Entity and DTO packages I have some code that is equal - the same field ID with annotations, etc is being reported as a duplication by Sonar. It has absolutely no sense to me so I'd like to disable it. How can I achieve this? Using the global exclusions option disables all metrics on selected package but how to do it just for code duplications?
With a newer SonarQube installation, you can use sonar.cpd.exclusions to exclude certain files only from duplicate checks.
See: https://docs.sonarqube.org/latest/analysis/analysis-parameters/
Example:
sonar.cpd.exclusions=**/AssemblyInfo.cs,**/*.g.cs,**/Mappings/*.cs
You can exclude resources using the standard "sonar.exclusions" parameter or use the Switch Off violation plugin to exclude "Duplicated code" violations.
Note that the 2nd option (use of the switch off plugin) works only if you're using the SQALE plugin, which embeds the "sqale-java:DuplicatedBlocksCheck" rule.
For me works its:
<sonar.cpd.exclusions>
com.simulate.java.dto\**
<\sonar.cpd.exclusions>
I have mult modules java projects just like that:
- parent
-- project-a
-- project-b
-- project-c
in the pom.xml of parent project inside of tag <properties> i put:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<sonar.cpd.exclusions>
com.simulate.java.vo\**,
com.simulate.java.dto\**
<\sonar.cpd.exclusions>
<\properties>
Just like that. I hope I helped you.
You can add these files to the properties in your pom.xml:
This one is to exclude from code coverage:
<sonar.coverage.exclusions>
your file paths
</sonar.coverage.exclusions>
This one is to exclude from code duplication:
<sonar.cpd.exclusions>
your file paths
</sonar.cpd.exclusions>

How to use a single checkstyle suppression file in Maven for all modules

I have a project that consists of several Maven modules which are all children of a parent module.
I have the parent set up to use checkstyle and the child modules all inherit this behaviour correctly. I would like all the child modules to use the parents suppression file defined in its plugin.
I define a property checkstyle.suppression which is used in the checkstyle plugin
<properties>
<checkstyle.suppressions>${basedir}\src\checkstyle\suppressions.xml</checkstyle.suppressions>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.2</version>
<configuration>
<configLocation>config/sun_checks.xml</configLocation>
<suppressionsLocation>${checkstyle.suppressions}</suppressionsLocation>
<suppressionsFileExpression>${checkstyle.suppressions}</suppressionsFileExpression>
</configuration>
</plugin>
</plugins>
Which works fine for the parent but all the child modules try to find the file in their basedir which does make sense.
I am sure there must be a simple solution I am missing but is there a way to define this location so that all the child modules will use the parent location without hard coding it?
The answers above are dangerous. I maintain that each project should be self contained, so referring to files external to it is going to break a build sooner or later. Checkstyle can take a url for the file but that means you can't build offline. A better approach is to package your file (can also add pmd.xml) into a jar and then add that jar to the classpath of the checkstyle (or pmd) plugin. I have an example of it here and more about overridding a plugin classpath here
The plugin's documentation mentions a similar use case here:
http://maven.apache.org/plugins/maven-checkstyle-plugin/examples/multi-module-config.html
Have you tried defining the property like this in the parent pom or redefining it in the childrens?
<properties>
<checkstyle.suppressions>${parent.project.basedir}\src\checkstyle\suppressions.xml</checkstyle.suppressions>
</properties>
If the parent isn't going to run checkstyle, you might just be able to rewrite it to
<properties>
<checkstyle.suppressions>..\..\src\checkstyle\suppressions.xml</checkstyle.suppressions>
</properties>
Or something like this. Or you could put something in settings.xml to point everything to an system wide config directory.
While it might not be recommended, you can have use a boot-strap or set-up project or task put a copy of the suppressions.xml file to a location specified by a property in settings.xml and then always refer to it by that locations.

Can I move maven2 "target" folder to another device?

I would really like to make maven write the "target" folder to a different device (ramdisk), which I would normally consider to be a different path. Is there any maven2-compliant way to do this ?
I am trying to solve this problem on windows, and a maven-compliant strategy would be preferred.
If you happen to have all of your projects extending a corporate parent pom, then you could try adding Yet Another Layer of Indirection as follows:
Corporate POM:
<build>
<directory>${my.build.directory}</directory>
</build>
<properties>
<!-- sensible default -->
<my.build.directory>target</my.build.directory>
</properties>
In your settings.xml:
<properties>
<!-- Personal overridden value, perhaps profile-specific -->
<my.build.directory>/mnt/other/device/${project.groupId}-${project.artifactId}/target</my.build.directory>
</properties>
If the local POM definition takes precedence over the settings.xml definition, then you could try omitting the default value at the cost of having every Maven instance in your control (developers, build machines, etc) specify ${my.build.directory} in its settings.xml.
Actually, Maven is not as constrained as everybody thinks, all the POMs are extended of one Super POM in which is defined the name of the target folder
<build>
<directory>target</directory>
<outputDirectory>target/classes</outputDirectory>
<finalName>${artifactId}-${version}</finalName>
<testOutputDirectory>target/test-classes</testOutputDirectory>
.
.
.
</build>
Of course you can overwrite with any value you want, so just go ahead and change the <directory /> element (and other related elements) in your POM
just in case if you want to fix this for your own Maven3 and not touch anything in the project, locate file:
$MAVEN_HOME/lib/maven-model-builder-3.X.Y.jar
and update super-pom inside
org/apache/maven/model/pom-4.0.0.xml
changing line
<directory>${project.basedir}/target</directory>
in
<directory>/tmp/maven2/${project.groupId}-${project.artifactId}/target</directory>
so next time when you will build any maven project - it will put all classes under /tmp/

Categories