Maven - access properties file from dependency - java

Expanding upon this question, if using a properties file in the dependency is the original question possible?

Usually you would do the following:
Create a pom-packaged project, using it as a parent pom
in this parent pom, read the property files you want to read using the Maven properties plugin by binding it's read-project-properties goal to the validate phase.
Refer to this parent pom in all the poms that shall share the properties read.

Related

Access file present in /test/resources - classpath issue

I'm working on a Spring multi-module project. One of the child modules has some files under /test/resources/certs/ and a property file under /test/resources/test-ssl.properties.
───resources
│ test-ssl.properties
├───certs
│ test-keystore.p12
test-ssl.properties has a property that points to /certs/test-keystore.p12file.
server.ssl.trust-store=/certs/test-keystore.p12
In child modules pom.xml I'm using Maven plugin test-jar and in parent pom I've added this module as a dependency.
With this structure integration test present in parent module is able to successfully read classpath:test-ssl.properties but it fails to resolve its property value.
Spring throws FileNotFoundException: \certs\test-keystore.p12. What change we can do to make Spring read a file present in test jar?
Also tried the following patterns,
server.ssl.trust-store=classpath:/certs/test-keystore.p12
server.ssl.trust-store=classpath:certs/test-keystore.p12
server.ssl.trust-store=classpath*:/certs/test-keystore.p12
Please note that this test property doesn't try to load any certificate. It is there because property placeholder can find some value for the property during build.
Issue is resolved by changing integration-test phase to process-test-resources.
Credit goes to the following answer of Pascal Thivent:
The content of the test output directory (target/test-classes) is on the class path, not src/test/resources. But resources under src/test/resources are copied to the test output directory by the resources:testResources goal (which is bound by default to the process-test-resources phase).

Using Maven, how can a child module inherit the parent module's repository?

Currently my web app has a spring-boot/java backend and an angular5/node frontend. I am using a Maven wrapper to encapsulate the projects such that the backend and frontend are both linked via the parent pom.
I am now configuring my database and I am putting the repository information in the parent pom. "I have heard that this is best practice because it enables you to access the db from other future projects. Ex Android app"
What do I need to include in my parent/child pom so that my backend module is reading from the parent repository?
Thank you!
This might be possible but not sure because not too familiar how Spring is configured.
In the parent projects pom.xml all the main or profile related <properties /> are usable in child projects also.
With proper filtering you can use properties set in parents pom.xml to be set in your child project configuration files.
So for a dummy and abstract (totally Spring configuration unrelated but jsut to show how it could work) example, with
pom.xml (parent)
<properties>
<db.url>jdbc:postgresql://127.0.0.1:5432/MyDb</db.url>
...
<properties>
and
some configuration / property file
db.url=${db.url}
the result for filtering would be
db.url=jdbc:postgresql://127.0.0.1:5432/MyDb
See also this filtering related post.

Why sometimes dependency not contain version property in pom.xml?

I am a newbie of Maven, currently reading Hadoop source code, and found something interesting in some pom.xml files:
Some of the dependency node do not contain version node at all.
Question: why is it like this?
for instance, this pom.xml.
Because specific version of dependency in parent pom.xml file
https://github.com/apache/hadoop/blob/trunk/pom.xml
Reference: https://maven.apache.org/guides/introduction/introduction-to-the-pom.html
As I commented at first, a pom file can have a parent (via inheritance) and such a parent may provide some governance and harmonization across all of its children. A classic case is to provide versioning for certain dependencies via a dependencyManagement section.
is used by POMs to help manage dependency information across all of its children. If the my-parent project uses dependencyManagement to define a dependency on junit:junit:4.0, then POMs inheriting from this one can set their dependency giving the groupId=junit and artifactId=junit only, then Maven will fill in the version set by the parent. The benefits of this method are obvious. Dependency details can be set in one central location, which will propagate to all inheriting POMs.
The mentioned pom has indeed a parent pom:
<parent>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-project-dist</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../../hadoop-project-dist</relativePath>
</parent>
Which in chain has another parent pom file which defines several dependencies as part of its dependencies management section.
If you really want to check the effective (merged) pom your build is using, you could run:
mvn help:effective-pom -Doutput=effective-pom.xml
And the maven-help-plugin will produce an additional pom as specified by the command above, merging the current pom file and all of its anchestors.
In Maven you can inherit from parents folder in order to merge or inherit some properties. This can be the version of the modules. Usually you have a "super" POM in the root folder of your project and you put there all the commons dependencies in order to controll them in an easier way. I.e. If you must change one module version, you only need to change in the "super" POM and not in each POM inside each subfolder that need it. If you need more information about POM inheritance the documentation has a couple of useful examples.
https://maven.apache.org/guides/introduction/introduction-to-the-pom.html#Project_Inheritance

How to create a maven archetype with both inherited and aggregated modules?

I am using mvn archetype:create-from-project within a manually created project
This project has both inherited and aggregated modules.
However when creating a new project based on this fresh archetype, the aggregated module pom file always finds itself injected with <parent>..</parent> attribute thus inheriting rather than being aggregated, which screws up the build order.
How can I prevent this aggregated module to be injected with <parent> tag?
It's actually not possible.
There's an open request for it on their JIRA from November 2011:
As mentioned in ARCHETYPE-110, the current implementation overwrites parent information if there are no existing parent definition inside the body of the pom.xml. So if we don't want such declaration we haven't no alternatives.
Source: https://jira.codehaus.org/browse/ARCHETYPE-393

Set maven property from plugin

I've read some questions here about how to set a property (most of them talked about the version number for an application) from a maven plugin.
It seems there's no easy way of doing this and the best solution I found is to have a filter.properties file which is updated from the plugin and used by the main pom file to filter the desired resources.
I tried another solution after I read this from the Maven documentation (Maven filter plugin):
Variables can be included in your resources. These variables, denoted
by the ${...} delimiters, can come from the system properties, your
project properties, from your filter resources and from the command
line.
I found interesting that variabled can be read from system properties. So, I modified my plugin to set a system property like this:
System.setProperty("currentVersion", appCurrentVersion);
However, filtered resources don't seem to read this value.
Could anybody tell me what's wrong with this approach?
UPDATE: I'm running my plugin in the validate phase.
Thanks a lot.
Don't set it as System Property, set it as Maven Project property
// inject the project
#Parameter(defaultValue = "${project}")
private org.apache.maven.project.MavenProject project;
// and in execute(), use it:
project.getProperties().setProperty("currentVersion", appCurrentVersion);
See:
Mojo Developer Cookbook
MavenProject javadoc
An edit suggested using Properties.put() instead of Properties.setProperty(). While technically, Properties implements Map, this usage is discouraged explicitly in the Properties javadoc.
Maven sets properties in initialize phase. I assume that in that phase maven loads system properties. And after that maven doesn't load system properties again. If you try to add a system property after this phase than it's not loaded.
Try to run your plugin in validate phase.

Categories

Resources