How to create custom files from tests in Maven - java

I have a tests writen in TestNG and running through Maven Surefire. In the tests there are lot of database updates and inserts and I want to create a report of which inserts or updates couldn't be performed (because of invalid data, or whatever). For that I would like to create a CSV file where I will track the IDs and exception messages. I want this file to be created in the target directory of my project (and all of the subprojects). How can I obtain the configuration from maven and use the directory to have all things together? I don't want to hardcode the path to file.
Thank you,
Filip

You have to think the other way around: which information should Maven push to/for my test (instead of: how can I pull information from Maven).
One option: create a test.properties under src/test/resources and add outputDirectory = ${project.build.testOutputDirectory} to this file.
In your pom.xml specify
<build><testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<testResource>
...etc
Now you can read this file from the classpath and use it in your tests.

Related

exclude file from maven's resource directory

I am using maven for my spring boot application(1.5 version). There are some files in src/main/resources like abc.properties, app.json. Below are some pointer what i want to achieve.
Exclude these files getting into the jar.
When i run my application through intellij these files should be available in classpath.
I looked at related answers on SO but none matches my case. Any suggestion?
you can use the resouce tag in maven pom file:
<resources>
<resource>
<directory>[your directory]</directory>
<excludes>
<exclude>[non-resource file #1]</exclude>
<exclude>[non-resource file #2]</exclude>
<exclude>[non-resource file #3]</exclude>
...
<exclude>[non-resource file #n]</exclude>
</excludes>
</resource>
...
</resources>
For more informations see: https://maven.apache.org/plugins/maven-resources-plugin/examples/include-exclude.html
My understanding is
You want some config file, that is available in classpath during runtime
Such config file will be changed based on environment
The way I used to do is:
Create a separate directory for such kind of resources, e.g. src/main/appconfig/
Do NOT include this in POM's resources (i.e. they are not included in resulting JAR)
In IDE, add this directory manually as source folder (I usually put this in testResource in POM. When I use Eclipse + M2E, testResources will be added as source folder. Not sure how IntelliJ though)
For point 2, I used to do it slightly differently. Instead of excluding, I will include in the result JAR but in a separate directory (e.g. appconfig-template), so that people using the application can take this as reference to configure their environment.
An alternative of 3 is: create a separate profile which include appconfig as resource. Use this profile only for your IDE setup but not building your artifact.

Spring boot, environment specific properties location

I can see many posts regarding environment specific properties, but none of them is quite solving my problem.
I'm working on my spring boot app, which will have say two profiles dev/live.
I want my project to have the following structure:
--deployment
--dev
--myapp.properties
--live
--myapp.properties
--src
--main
--java
--resources
--test
--java
I know that if I had two application.properties in my resources folder, say application-live.properties and application-dev.properties I'd be able to tell maven which one to pick at application start time using:
Dspring.profiles.active=profile_name
But I don't like name of this generic properties file. So I found this way to tell the application where to look for profile specific properties in /deployment/<profile>/.
I did it using Maven build task configuration:
<build>
<resources>
<resource>
<directory>deployment/${environment}</directory>
<includes>
<include>*.properties</include>
<include>*.xml</include>
</includes>
</resource>
</resources>
</build>
This is going to search for resources in deployment/<profile> and include them. Good thing is that Maven finds the correct environmental property files, but unfortunately it includes them in target/classes/myapp.properties which seems invisible for Spring Boot? How can I tell Maven to place it in the same directory as application.propertiesor alternately how can I tell Spring Boot to find it where it is at the moment?
Thanks a lot!
How can I tell Maven to place it in the same directory as application.propertiesor alternately how can I tell Spring Boot to find it where it is at the moment?
1) you don't need to modify Maven settings because it places config file to the right place: target/classes is the root of the classpath, because all files from this directory will copied into the WEB-INF/classes directory of you WAR/JAR file.
2) to change name of the properties file from you can use spring.config.name property by explicitly passing it as -Dspring.config.name=myapp or as environment variable SPRING_CONFIG_NAME=myapp. More information you can find in the Change the location of external properties of an application chapter of the official documentation.

ImplementedVersion is not accessible in exec:java target

I have used this how2 to add the Version number to our produkt: http://www.christophkiehl.com/easy-way-to-display-your-apps-version-using-maven-and-manifest
when i now build a jar with mvn assembly:single i see the correct version.
But when i just run everything with mvn exec:java i get null...
what do i have to do that App.class.getPackage().getImplementationVersion() does not return null when i just start the programm from the non-jar?
The technique that you have used to add version number works only when built as a jar.
A different way to achieve the same would be to have a properties file which gets updated with the project version during build, which in turn is read by your java code.
Say, you have a file version.properties in src/main/resources, which has an entry
product.version=${project.version}
In the place you call App.class.getPackage().getImplementationVersion(), you read this property and display the contents.
This will work in both jar and non-jar case.
Update: You would need to update the pom to enable filtering for resources - essentially add a snippet like the below (refer this for details).
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

Is there a way to automatically replace a pattern in .java file on build-time?

I want to be able to replace specific pattern in .java files on build time. In fact, I just want to replace certain String value to represent build time. (And I also want to leave original source file intact). Is there a way to do it easily (apart from manual way)?
I'm using NetBeans as my IDE.
At best do not put this pattern in java file, but load it from resource, f.g. .properties file.
Maven has resource filtering features, you can then use profiles to change particular resources, or copy resources from other locations. Ant given you also the opportunity to use various resources locations.
You can always copy another properties file manually. In all cases source java file is intact. The code runs from your IDE and you can change pattern not recompiling the code.
We needed something similar for our product (embed build time, build computer & user name into the compiled application).
We used ant's manifest task to embed a manifest into the jar which contains the information we needed. See http://ant.apache.org/manual/Tasks/manifest.html .
The manifest can easily be read from the JAR using tools. If you need the information in your software, you can read it programatically, or put it into a .properties files (generated at build) which you can read from the program.
I am not sure about editing Java code. But if you use maven, there is way work this out. Make a properties file, make a util class that reads the properties file for you. Use this class in other classes where you want the properties to be replaced at build time.
Basically,
Create a config.properties that has
myprop1=${val1}
myprop2=${val2}
Write a maven pom.xml that has profiles and do this
<profiles>
<profile>
<id>local</id>
<properties>
<val1>localval1</val1>
<val2>localval2</val2>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<val1>prodval1</val1>
<val2>prodval2</val2>
</properties>
</profile>
</profiles>
Make a class that reads this config.properties. And use it to read dynamic data.
Build using mvn -Plocal clean install or mvn -Pprod clean install to values gets replaced in config.properties based on profile.
Hope this helps.
With ANT, you can do the same. In ANT, you create multiple config files say, local.config.properties and prod.config.properties. At the build time, you can pass a parameter like 'local' or 'prod'.
Do resource copy where you copy appropriate file based by prepending the parameter to config.properties (thus copying local.config,properties ot prod.config,properties). And after copying to classpath, rename to config.properties
I think Ant or Maven could be of assistance to you - do you use either of these to perform your build? I've not used Maven but have done something similar in Java.
Try using Ant "replace" task, here's an example:
<replace file="${src}/index.html" token="###" value="wombat"/>
replaces occurrences of the string "###" with the string "wombat", in the file ${src}/index.html.

Including .properties files with .class in JAR after an mvn install

Imagine I have a project I want to build using maven. My project doesn't, unfortunately, respect the maven default layout. So I'm having two source folders A & B containing .properties files with .java sources.
After an mvn install, my .properties files are not packaged in the jar with my .class generated files. Is there a way to do this automatically, you'd probably propose to use <resources> tag to solve this kind of problems; this obviously works I know, but i'll have to each time specify where my .properties files are stored, and where I want them to be packaged in the JAR, this is not a solution for me since I have multiple source folders (hundreds) regularly updated.
<resource>
<targetPath>com\vermeg\jar2</targetPath>
<filtering>true</filtering>
<directory>${basedir}/a/jar2</directory>
<includes>
<include>*.properties</include>
</includes>
<excludes>
<exclude>*.java</exclude>
</excludes>
</resource>
Will I have, for each source folder, to write this in my POM, does anyone knows a simpler automatic way to do this ?
Regards,
Generally you can use Maven properties and profiles to solve this kind of problem.
For example edit your pom to:
<resource>
<targetPath>${myresources.targetpath}</targetPath>
<directory>${myresources.directory}</directory>
...
</resource>
and define myresources.directory and myresources.targetpath in command line using -Dname=value or in conditional profile or by using other properties available in your build.
If you explain your project structure and/or conditions and their relation to your variable (targetPath and directory) I may be able to help more with your question.
Specify it once in a parent pom instead, and all the children should inherit the same setup...
Would it be impossible to change to using the standard Maven layout, with all your properties in a parallel 'package' hierarchy under src/main/resources? Then you don't need to specify anything; all .properties files will be packaged.
If you do this, you'll need to enable filtering as it's off by default. You may have to explicitly declare the resource directories again, as when you declare them, this seems to override the ones you get 'for free'.
As for your multiple source folders, a multi-module Maven project would probably be the best fit, with A and B being children of some new parent project.
This might seem like quite a lot of work, but Maven's conventions are fairly reasonable, and it tends to be a painful experience if you go against them.

Categories