How to use pom.xml property in junit test class - java

I have declare a property in pom.xml
<PROPERTY_KEY>d:/../.../abc.properties</PROPERTY_KEY>
and then used
<plugin>
<configuration>
<replacements>
<replacement>
<token>APP_PROPERTY</token>
<value>${PROPERTY_KEY}</value>
....
</plugin>
and have used APP_PROPERTY in my dispatcher-servlet.xml and in controller classes as well. It's working fine as in this case control comes through web.xml and this web.xml has an entry for my dispatcher-servlet.xml.
But when I want to use this same APP_PROPERTY in my JUNI test class, it is not getting resolved.
I have to create a new dispatcher-servlet-test.xml file (and put it under /src/main/resources folder) as my actual dispatcher-servlet.xml is not working from JUnit test class. Now my JUnit test class is able to pick dispatcher-servlet-test.xml. But, it is not able to resolve properties (APP_PROPERTY) that I have defined in my pom.xml.
I'm using SpringJUnit4ClassRunner.class in my test class.
What should I do to get these property resolved?

Resources for tests need to live under src/test/resources, you should move your dispatcher-servlet-test.xml there. Once moved, it's likely not being filtered as a resource, the stanza you want is something like:
<build>
<resources>
<resource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/dispatcher-servlet-test.xml</include>
</includes>
</resource>
You may already have a similar stanza in your POM, or if you're working on a larger project the parent pom.xml may have a stanza declaring:
<filtering>true</filtering>

Related

Non-java resources disappear from class package after maven packaging

I'm trying to create a Spring project structure where I have my HTML templates stored in the same src/main/java package (in Tapestry-like way), so the structure basically looks like this:
src/main/java
-org
-example
-views
-pageOne
PageOneController.java
Template.html
-pageTwo
PageTwoController.java
Template.html
However after packaging a WAR while using Maven I get a structure like this:
WEB-INF/classes
-org
-example
-views
-pageOne
PageOneController.class
-pageTwo
PageTwoController.class
So the .html files are ignored and obviously nothing works.
I tried to configure maven-resources-plugin to copy those resources like this:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<filtering>false</filtering>
<includes>
<include>*/**.html</include>
</includes>
<excludes>
<exclude>*/**.java</exclude>
</excludes>
</resource>
</resources>
</build>
but to no avail.
How do I configure my project to copy non-java files from src/main/java into the final output?
It turns out that the problem was with maven modules. I have declared resources plugin in the main pom.xml instead of the module's pom.xml which lead to the configuration issues.

How to retrieve <finalName> value from POM?

I manually set the tag value in my pom.xml before I packaged my Spring web app to .war and then I manually deploy my .war file on JBOSS.
I have an test.html file in webapp folder which is sending an POST request to test if #RequestMapping methods inside my controller class are working as expected or not. I want to store the value of tag in the JavaScript variable (in test.html).
How can I fetch the value from pom.xml and store in the JavaScript variable?
Make a filtered property resource file that has ${finalName} in it, and then read that in from your classpath.
src/main/resources/config.properties:
finalName=${propContainingFinalName}
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>config.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>

Getting version from pom in JSP for Spring Boot Web

I was trying to print the application version from pom.xml in my JSP pages. i tried combing the filtering with Spring boot.
But the values are not rendered in the jsp pages.
I added the below section in pom.xml.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>src/main/resources/templates</directory>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>
And addded the below in jsp pages:-
<h4>${project.description}</h4>
<h4>${project.name}</h4>
<h4>${project.version}</h4>
But when the JSP page renderes the tags are empty with no values in it.
I was trying to solve very same issue: basically to insert value of project variables statically into JSP generated at build time. Without additional call to get properties etc at run time. Here is a snippet that solved it for me.
I am using spring and it is using maven-war-plugin underneath.
I put all files that I need static values into subfolder so not all jsps are filtered. Later I static include such files.
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>src/main/webapp/WEB-INF/jsp/version/</directory>
<filtering>true</filtering>
<targetPath>WEB-INF/jsp/version/</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
As described in the documentation, Spring Boot uses #…# as the delimiter rather than ${…}:
since the default config files accept Spring style placeholders (${…​}) the Maven filtering is changed to use #..# placeholders (you can override that with a Maven property resource.delimiter)
This means that your JSP needs to contain the following:
<h4>#project.description#</h4>
<h4>#project.name#</h4>
<h4>#project.version#</h4>
Also, AFAIK, filtering for src/main/resources/templates should be enabled like this:
<resources>
<resource>
<directory>src/main/resources/templates</directory>
<filtering>true</filtering>
</resource>
</resources>

cdi not working when using maven filters

I'm trying to add maven filtering to a project i'm working on, but after I build the project with filtering on, all of the injected beans are null. Here is the addition to the pom:
<build>
...
<filters>
<filter>${basedir}/build.properties</filter>
</filters>
<resources>
<resource>
<directory>${basedir}/misc/jboss</directory>
<filtering>true</filtering>
<targetPath>${basedir}/filtered</targetPath>
<includes>
<include>manager.properties</include>
</includes>
</resource>
<resource>
<directory>${basedir}/misc/jboss</directory>
<filtering>false</filtering>
<targetPath>${basedir}/filtered</targetPath>
<excludes>
<exclude>*.jar</exclude>
<exclude>*.keystore</exclude>
<exclude>*.xml</exclude>
</excludes>
</resource>
</resources>
...
</build>
I notice that the beans.xml file is missing from the .war file.
I don't understand why the beans.xml is missing, since I'm only applying the filering on a specific directory <directory>${basedir}/misc/jboss</directory>...
When I remove the above from the pom everything is working again.
Any ideas?
Looks like you're excluding all *.xml files from the build:
<exclude>*.xml</exclude>
Which is probably causing the problem.
I suspect you either want to remove the exclusions, or add corresponding include elements to the section with filtering set to true.
You probably also want to add a corresponding exclusion for
<include>manager.properties</include>
The problem was indeed related to the <exclude>*.xml</exclude> as suggested by #cowls.
But the root cause was due to the fact that when there's at least one <resource> element then the default filtering behavior doesn't apply anymore.
The default filtering behavior is to includer resources under src/main/resources in the build, without filtering. So without that default behavior, the beans.xml which was under src/main/resources wasn't included in the build, thus CDI stopped working.
In order to fix this issue, a 'default' resource had to be included:
<resource>
<directory>src/main/resources</directory>
</resource>
More information can be found here.

If using maven, usually you put log4j.properties under java or resources?

Where should I put the log4j.properties file when using the conventional Maven directories?
src/main/resources is the "standard placement" for this.
Update: The above answers the question, but its not the best solution. Check out the other answers and the comments on this ... you would probably not shipping your own logging properties with the jar but instead leave it to the client (for example app-server, stage environment, etc) to configure the desired logging. Thus, putting it in src/test/resources is my preferred solution.
Note: Speaking of leaving the concrete log config to the client/user, you should consider replacing log4j with slf4j in your app.
Just putting it in src/main/resources will bundle it inside the artifact. E.g. if your artifact is a JAR, you will have the log4j.properties file inside it, losing its initial point of making logging configurable.
I usually put it in src/main/resources, and set it to be output to target like so:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<targetPath>${project.build.directory}</targetPath>
<includes>
<include>log4j.properties</include>
</includes>
</resource>
</resources>
</build>
Additionally, in order for log4j to actually see it, you have to add the output directory to the class path.
If your artifact is an executable JAR, you probably used the maven-assembly-plugin to create it. Inside that plugin, you can add the current folder of the JAR to the class path by adding a Class-Path manifest entry like so:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.your-package.Main</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Now the log4j.properties file will be right next to your JAR file, independently configurable.
To run your application directly from Eclipse, add the resources directory to your classpath in your run configuration: Run->Run Configurations...->Java Application->New select the Classpath tab, select Advanced and browse to your src/resources directory.
Some "data mining" accounts for that src/main/resources is the typical place.
Results on Google Code Search:
src/main/resources/log4j.properties: 4877
src/main/java/log4j.properties: 215
The resources used for initializing the project are preferably put in src/main/resources folder. To enable loading of these resources during the build, one can simply add entries in the pom.xml in maven project as a build resource
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
Other .properties files can also be kept in this folder used for initialization.
Filtering is set true if you want to have some variables in the properties files of resources folder and populate them from the profile filters properties files, which are kept in src/main/filters which is set as profiles but it is a different use case altogether. For now, you can ignore them.
This is a great resource maven resource plugins, it's useful, just browse through other sections too.
When putting resource files in another location is not the best solution you can use:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<build>
For example when resources files (e.g. jaxb.properties) goes deep inside packages along with Java classes.
If your log4j.properties or log4j.xml file not found under src/main/resources use this PropertyConfigurator.configure("log4j.xml");
PropertyConfigurator.configure("log4j.xml");
Logger logger = LoggerFactory.getLogger(MyClass.class);
logger.error(message);
Add the below code from the resources tags in your pom.xml inside build tags.
so it means resources tags must be inside of build tags in your pom.xml
<build>
<resources>
<resource>
<directory>src/main/java/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<build/>

Categories