If I have a pom.xml like
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<resource.filtering>true</resource.filtering>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>${resource.filtering}</filtering>
<includes>
<include>environment.properties</include>
</includes>
</resource>
</resources>
</build>
</project>
Eclipse marks the <filtering>${resource.filtering}</filtering> line with a validation error, because the schema tells it this should be a boolean, and that doesn't look like a boolean. I would rather not shut off the pom.xml validation, and it's annoying to see the error on the project. My goal is to be able to control whether resource filtering occurs based on Maven profiles. Is there a way of doing this that passes Eclipse's validation? I'm using Eclipse Luna (4.4).
I asked a similar question, and even tried filing a bug report with the Eclipse team. The answer I got was, "This is a result of an inherent conflict between the xsd that describes the pom format, and the aims of the pom file." So other than turning off validation, there isn't much one can do about these error messages.
Related
I have a Maven project with a submodule, developed in IntelliJ, using Java 11.
Unless the pom.xml file contains <packaging>pom</packaging>, there is a warning that
'packaging' with value 'jar' is invalid. Aggregator projects require 'pom' as packaging.
But when packaging is set to "pom", the resource file that I need can't be loaded; a null value is returned, and an exception is thrown. From the main() method:
URL resource = getClass().getResource("/fx/gui.fxml");
Objects.requireNonNull(resource);
On the other hand, sometimes the submodule is not found, unless I ask for pom packaging. What I do then is: Request pom packaging, start the program and watch it fail, remove the pom packaging statement from pom.xml, start again and the program works.
My resource file is in the standard location src/main/resources/fx/gui.fxml. This location is also given in the pom file:
<build>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
</build>
Please help me understand what's going on. Do I need pom packaging, and how can resources be loaded with it?
Looks like you have your source code in your parent pom.
A parent pom (with sub-modules) must have packaging as pom and cannot have java source code. See this question
You should move your code in a new sub-module.
The project or module which contains the source code, has to have the packaging as jar/war as per your requirement. It can not be packaging as pom. Generally pom packaging is used with parent module when you have multimodule project structure and the submodules would have packaging as jar/war. So in your case, if you have multimodule project structure, your parent packaging would be "pom" and all submodules(contain source code) must have jar/war. Note : Your parent module should not have source code, if it is then move your source code to submodule. Multimodule project structure is basically used where there are common dependencies and artifacts can be used in multiple submodules so that duplication can be removed.
Like below.
parent pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.abc.test</groupId>
<artifactId>testartifact</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<modules>
<module>rest-services</module>
</modules>
</project>
Submodule pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.abc.test</groupId>
<artifactId>testartifact</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>rest-services</artifactId>
<name>rest-services</name>
<dependencies>
<dependency>
</dependency>
</dependencies>
</project>
It was a little bit hard to come up with a meaningful title, hope it will become clear enough after the explanation. I have searched through a number of Qs and As on SO, and they were all very close to the problem I am experiencing, but still not close enough.
In general, what I want to accomplish is to store project version in DB by accessing the maven property #project.version# from a .csv file which is loaded by a Liquibase script.
My maven project structure looks like this:
parentModule
pom.xml
|
---moduleA
|__pom.xml
---moduleB
|__pom.xml
---moduleC
|__pom.xml
...
Pom.xml are defined as:
**PARENT POM**
<project ...>
<groupId>com.parent</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<name>parent</name>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.2.1.RELEASE</version>
<relativePath />
</parent>
<properties>
<java.version>8</java.version>
</properties>
<modules>
<module>moduleA</module>
<module>moduleB</module>
<module>moduleC</module>
...
</modules>
<build>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
----------------------------------------------------------------------
**CHILD POM**
<project ...>
<artifactId>moduleC</artifactId>
<name>moduleC</name>
<parent>
<groupId>com.parent</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
</parent>
<dependencies>
<dependency>
...
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>moduleC/src/main/resources/db/changelog/</directory>
<filtering>true</filtering>
<includes>
<include>**/app_version.csv/</include>
</includes>
</resource>
</resources>
</build>
</project>
Liquibase scripts are defined in moduleC/src/main/resources/db/changelog/changelog-master.xml etc., while the .csv files with initial values are located in moduleC/src/main/resources/db/users.csv etc. In one of those csv files, I want to push #project.version# value, like this:
id;app_key;app_value;created_by;last_modified_by
1;app-version;#project.version#;system;system
Since that file is located in moduleC, I used maven resource filtering even inparentModule <build/> to filter that file so it can resolve #project.version# property, but with no luck:
<build>
<resources>
<resource>
<directory>moduleC/src/main/resources/db/changelog/</directory>
<filtering>true</filtering>
<includes>
<include>**/app_version.csv/</include>
</includes>
</resource>
</resources>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
There are errors, one that says that master changelog cannot be found, while in other cases just string value #project.version# is stored. Seems to me I should include app_version.csv and its location (moduleC) as resource inside <build> tag withing parentModule pom.xml, but every combination of referencing it fails. Is there a solution to reference it properly (either from parentModule or moduleC pom.xml) or there might be an easier way to store #project.version# with liquibase?
I am extremely sorry for not replying on time, was temporarily removed from the project after posting the question and was not able to access the git repository due to change of location. So far, I have tried all of the proposed actions, but with no result. In the end, what I found to work was an accepted answer posted here. I have added the build block inside mavenC module pom.xml and it worked. Nevertheless, thank you all immensely for posting and helping.
I think you need to use the maven-replacer-plugin in your build cycle. It will be configured to process the 'app_version.csv' file and output the substituted file content to the 'target/classes' folder. The subsequent packaging phase will ensure the csv file with the current pom version will be bundled into the artifact that the liquidbase tool then handles.
Looks like you're using the wrong syntax for filtering in the CSV-file. Instead of using #project.version#, try ${project.version} instead:
Check the <directory>moduleC/src/main/resources/...</directory>, if the resources plugin lives in the child POM of moduleC then there is no need for the prefix.
Try replacing with <directory>src/main/resources/..</directory>
Resources filtering of a module should be in the build of the module itself.
The project.version property will be inherited from the parent.
Be careful so the filtering does not mess with your xml files.
I think the syntax should be ${project.version}
Can you share your liquibase maven plugin configuration ?
The markup should point to your master changelog.
Here is two other solutions:
Another solution would be to create a liquibase changeset every time you create a new version. You can do it programmatically using liquibase java SDK in a spring component which run on startup of your project or create the changeset yourself.
Another solution would be to use Spring Boot Actuator to retrieve project version.
For this you need to add <goal>build-info</goal> in the goals of spring-boot-maven-plugin
I was trying to convert old java projects into maven build, but facing difficulties excluding source files:
when I set goal to install for the parent project to compile and build jar files for all the projects, it still tries to compile the mentioned excluded java file. Below is my pom.xml for that project:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.app</groupId>
<artifactId>CCAPS.Impl</artifactId>
<version>1.0.0</version>
<parent>
<groupId>com.app</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<relativePath>../Maven.Convertion/parent</relativePath>
</parent>
<properties>
...
</properties>
<dependencies>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/adjudication/mapper/BusinessAddendumItemDBOMapper.java</exclude>
<exclude>**/adjudication/mapper/ContactInfoDBOMapper.java</exclude>
<exclude>**/adjudication/mapper/IncomeDBOMapper.java</exclude>
<exclude>**/adjudication/mapper/IncomeItemDBOMapper.java</exclude>
<exclude>**/adjudication/mapper/InternationalAddressDBOMapper.java</exclude>
<exclude>**/adjudication/mapper/ReferralSourceDBOMapper.java</exclude>
<exclude>**/adjudication/interceptor/*.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
<sourceDirectory>${project.basedir}/src/net/ccapsws/ds/adjudication</sourceDirectory>
</build>
</project>
Last line for exclude is where the error throws when compiling:
[ERROR] \Maven Convertion\CCAPSAdjudication\DataSource.CCAPS.Impl\src\net\gc\ccapsws\ds\adjudication\interceptor\CCAPSDTOAuditInterceptor.java:[8,46] error: package net.ccapsws.validation.dictionary does not exist
The thing is I tried with the exclude declaration but since the src path is custom (${project.basedir}/src/net/ccapsws/ds/adjudicationm, for example, is the src path), I suspect maven doesn't recognize the path? Anyone can help with this?
NOTE that I'm not asking resource files, I want to compile files inside src folder but also willing to exclude specific java files during compilation.
EDIT: There's one another project referencing this project, but in the parent POM I'm putting that project after this project in the reactor sequence, so I don't think anywhere else is referencing this project.
The path issue looks similar to the problem answered by these links: https://stackoverflow.com/a/25262893/4055837 and https://stackoverflow.com/a/39450549/4055837
I want to fetch the artifactId from the pom.xml and use this artifactId to populate the properties file.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xxxxx</groupId>
<artifactId>fm-service</artifactId>
<packaging>war</packaging>
<version>x.x.x-SNAPSHOT</version>
</project>
application.preperties
email.subject = "ALERT - [artifactId from pom.xml]"
Is is possible to do so? If yes how, if no, then please suggest alternatives.
Maven provides a way to filter resources.
First, the file application.properties has to be put into the src/main/resources directory. Then its content has to be:
email.subject = "ALERT - ${project.artifactId}"
Last (but not least) simply add this configuration to your POM:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
Now all files in the resources directory will be filtered, which means that all variables inside are resolved.
I know that it is possible to configure Decorators in the "beans.xml" file that is embedded in the EAR to be deployed.
The problem is that I use the same EAR for all the environments, and the set of properties or specific configurations are stored in some folder outside the package.
I need to determine if a Decorator will be used or not "external beans.xml" or some similar mechanism (something that is outside the EAR).
Any ideas?
Thank you very much.
Normally, this won't work - standard means of enablement are beans.xml for per-archive approach and #Priority for global enablement. There is nothing like "external beans.xml".
Although there is a way to enable it with extension. You need to set up an extension and observe AfterTypeDiscovery event. From there you can
make use of public List<Class<?>> getDecorators(); which returns MUTABLE list of decorators - so you can add your own into the list (in a form of a Class). That should enable it.
Another scenario you can use, is to utilize build-time inclusion and processing.
If you know before hand, what properties activate specific decorators at build-time, then you can use maven resources, together with system properties, to define additional resources to be filtered, thus:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompant</groupId>
<artifactId>my-project-id</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<some.kind.of.selector.properties>$basedir}/src/main/resources/development</some.kind.of.selector.properties>
</properties>
<build>
<resources>
<resource>
<directory>${some.kind.of.selector.properties}</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>test</id>
<properties>
<some.kind.of.selector.properties>$basedir}/src/main/resources/test</some.kind.of.selector.properties>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<some.kind.of.selector.properties>$basedir}/src/main/resources/prod</some.kind.of.selector.properties>
</properties>
</profile>
</profiles>
</project>
The at build time, you can specify different beans.xml for every environment:
mvn clean install -Pprod
or even specify the property directly
mvn clean install -Dsome.kind.of.selector.properties=/path/to/additional/resources