IntelliJ IDEA won't find log4j2.xml after maven build - intellij-idea

I have a maven project with log4j2 (2.9.0) and a configuration file in /src/main/java/resources/log4j2.xml. As long as I stay in IntelliJ this works fine and it logs just like I configured it.
If I now make a mvn clean install in the terminal (Ubuntu 14) and then start the main method of my program in IntelliJ, I will get an error that it won't find the log4j2 configuration file:
ERROR StatusLogger No log4j2 configuration file found. Using default
configuration: logging only errors to the console. Set system property
'log4j2.debug' to show Log4j2 internal initialization logging.
As soon as I make Build -> Rebuild Project in IntelliJ IDEA it will work again.
I don't really understand how an external maven build could confuse IntelliJ IDEA to not take the .xml in the local source code.
Any idea?

I found the solution.
IntelliJ copies the resources per default to /target/classes and that's the place where IntelliJ actually takes the log4j2.xml from. My maven build didn't do that and IntelliJ didn't rebuild the project, so it couldn't find the log4j2.xml
My solution was to put the log4j2.xml in a resource section of the pom:
<resources>
<resource>
<directory>src/main/resources</directory>
<targetPath>${project.build.directory}/classes</targetPath>
<includes>
<include>**/log4j2.xml</include>
</includes>
</resource>
</resources>

Related

Maven update jar before packaging in WAR

I have a project where I am packaging a WAR using simple maven-war-plugin. Along with all other dependencies one of the dependency say 'abc.jar' which is getting packaged in war contains a default spring configurations which I would like to update with the custom one before packaging. I have maven profile configured to be activated if following build command applied;
mvn clean install -DframeworkPacakging=XYZ
I am trying to use 'truezip-maven-plugin' to overwrite my custom spring configurations inside in 'abc.jar' present in 'target/aretfacts-id/WEB-INF/lib' but when maven-war-plugin finishes I loose my changes because war plugin takes the file from dependency definition. How can I solve this issue and what are my options?
P.S. Distributing configuration is not desirable as this setup would be used for Embedded Jetty Server running within Eclipse
to prevent inclusion of the original jar file, I would use go for approach suggested on: https://www.mail-archive.com/users#maven.apache.org/msg38537.html
Use <scope>provided</scope> for this dependency to keep it out of the
lib directory.
to include the repackaged one, I'd follow suggestion from: How to make Maven copy resource file into WEB-INF/lib directory?
Try changing the configuration of the maven war plugin to include a webResource:
<configuration>
<webResources>
<resource>
<directory>pathtorepackagedjar</directory>
<includes>
<include>**/abc.jar</include>
<includes>
<targetPath>WEB-INF/lib</targetPath>
</resource>
</webResources>
</configuration>

Maven: How to add custom classpath entry for plugin execution?

UPDATE: It seems to be SoapUI maven plugin specific issue at first, but it's not, really, so please read through.
I'm running SoapUI plugin with Maven2 like this:
<plugin>
<groupId>eviware</groupId>
<artifactId>maven-soapui-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<settingsFile>${basedir}/src/test/resources/soapui-settings.xml</settingsFile>
<projectFile>${basedir}/src/test/resources/my-soapui-project.xml</projectFile>
<outputFolder>${project.build.directory}/soapui-output</outputFolder>
<printReport>true</printReport>
<junitReport>true</junitReport>
<exportAll>true</exportAll>
<soapuiProperties>
<property>
<name>soapui.logroot</name>
<value>${project.build.directory}/soapui-logs/</value>
</property>
</soapuiProperties>
</configuration>
</plugin>
It works perfectly and puts all soapui log files into ${project.build.directory}/soapui-logs/ with one exception: global-groovy.log which goes into basedir (seems to be bug in SoapUI log4j configuration).
I need an option to override soapui-log4j.xml file that comes with SoapUi maven plugin and fix GLOBAL_GROOVY_LOG appender from:
<param name="File" value="global-groovy.log"/>
to this:
<param name="File" value="${soapui.logroot}global-groovy.log"/>
In the past I ran SoapUI test programmatically from JUnit test and just placed updated soapui-log4j.xml file into src/test/resources/com/eviware/soapui/resources/conf/soapui-log4j.xml and it worked. Maven copies it into target/test-classes and adds that path to classpath to run unit tests.
Now the problem with SoapUI maven plugin is that I don't know how to add src/test/resources/com/eviware/soapui/resources/conf/soapui-log4j.xml to plugin's classpath. Is there anything similar to Surefire's additionalClasspathElements configuration option?
So in other words I want to know how to add additional class path entries to any generic maven plugin execution environment, not only SoapUI plugin.
It's possible to add to a plugins dependencies using the dependencies element. From the POM reference:
Additional dependencies that this project needs to introduce to the plugin's classloader.
I don't know how maven treats these dependencies, so it might place them after the plugin's own classes which effectively prevents overriding the log4j configuration, but give it a try; package the log4j configuration file in a jar and add it as a dependency to the plugin.

Maven: use dependencies from repository when running command line app?

I've used Maven to build my command line application. Now I'm going to distribute it as a jar file, and I need to handle the app's dependencies.
I don't want to include all dependencies in the jar file as described here.
The environment where my app will be run has Maven. I'd like Maven to run my jar looking at file META-INF/groupId/artifactId/pom.xml inside the package so it knows what the dependencies are and can find them in the repository.
Any ideas ?
Include a main class in the jar that 1) extracts the pom to a temporary file, and 2) launches a new maven process using this file with the -f parameter and the goals dependency:resolve and dependency:build-classpath
like this:
mvn -f /temp/tempfile.xml dependency:resolve dependency:build-classpath -DoutputFile=/temp/classpath.txt
then 3) reads the newly created classpath file and 4) launches a new java process using the new classpath file
java -cp yourjar.jar;<created classpath>
Your pom.xml will have to include all required repository information, of course
We can use, maven-jar-plugin instead, why because the classpath generated is not getting accommodated while copy paste with java command in command-line.
mvn -f /temp/tempfile.xml dependency:resolve dependency:build-classpath -DmdepoutputFile=/temp/classpath.txt
So wasn't able to succeed copying classpath.txt for the command,
java -cp yourjar.jar;<created classpath>
Mine is spring-boot application hence I have the following line with BOOT-INF/lib. For you it can be WEB-INF/lib in case of .war file or just lib/ in case of ant build based projects.
<classpathLayoutType>custom</classpathLayoutType>
<customClasspathLayout>BOOT-INF/lib/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>
BOOT-INF, comes up by spring-boot:repackage maven command and with the use of plugin,-spring-boot-maven-plugin that I have not Included here.
Please find maven-jar-plugin config here.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.pakage.SampleApplication</mainClass>
<!--<classpathPrefix>lib/</classpathPrefix>-->
<classpathLayoutType>custom</classpathLayoutType>
<customClasspathLayout>BOOT-INF/lib/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>
<!--<customClasspathLayout>BOOT-INF/lib/$${artifact.groupIdPath}/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>-->
</manifest>
</archive>
</configuration>
</plugin>

Maven2: Cargo plugin hot deployment & Jonas support

I am trying to get the Cargo plugin works on my maven project in order to benefit from war hot-deployment targetting the Jonas server.
The official documentation is not that clear on what is supported and what is not (for example you can find this: http://cargo.codehaus.org/Hot+Deployment but also this http://cargo.codehaus.org/JOnAS+4.x).
Anyway I have the following coniguration in for my war's POM:
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0</version>
<configuration>
<container>
<containerId>jonas4x</containerId>
<home>C:\JOnAS-4.8.4\nt\bin</home>
</container>
<configuration>
<type>existing</type>
<home>C:\JOnAS-4.8.4</home>
</configuration>
</configuration>
</plugin>
And when I run
mvn cargo:deploy
on my project, the war is copied to the Jonas webapps folder but there is no hot deployment. The file is only copied but the hot deploy Jonas command is not called so that my modifications are not available immediatly.
EDIT: I also tried to add a deployer configuration as suggested on the answers but the behaviour is the same (ie: war is copied but the Jonas hot deploy command is not called so that the war is not reloaded in Jonas).
Am I missing something or am I right saying the Cargo Maven plugin does not support Jonas Hot Deployement?
Thanks in advance!
The cargo page on deploying to a running container links to a table listing the version where hot deployment was introduced for that container. According to the table, JOnAS 4.x is supported from version 1.0 (which you are using), so it should work.
On that page it also has some guidelines for configuring the plugin for deployment, I've attempted to interpret them below.
From the home element in your configuration I assume you are attempting a local deployment. The configuration in the running container page implies that the hot-deployment should be automatic in this line at the end:
Just type mvn cargo:deploy. Notice that we haven't specified a element nor a one. This is because the plugin is smart enough to create default instances for you. Cool, isn't it?
However the earlier configuration block indicates you should configure the deployer section to make the cargo plugin aware of the war to be deployed. The configuration for the deployer would be something like this:
<deployer>
<type>local</type>
<deployables>
<deployable>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<type>war</type>
<properties>
<context>optional root context</context>
</properties>
<pingURL>optional url to ping to know if deployable is done or not</pingURL>
<pingTimeout>optional timeout to ping (default 20000 milliseconds)</pingTimeout>
</deployable>
</deployables>
</deployer>
If the automatic option isn't working for you, consider declaring the configuration for your war.

Spring Boot property expansion not working after switching from Eclipse to IntelliJ

Our app has for properties that we pick up dynamically from the Maven project files.
info:
build:
artifact: #project.artifactId#
name: #project.name#
description: #project.description#
version: #project.version#
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready-application-info-automatic-expansion-maven
When we were using Eclipse these were not a problem, but now on moving to InelliJ the app won't startup unless I provide some hardcoded values for those dynamic properties.
I get this error:
19:47:20.962 [main] INFO com.edlogics.ElrcApplication - Spring Boot configuration: profiles = [local, chris]
19:47:20.968 [main] INFO com.edlogics.ElrcApplication - Spring Boot configuration: properties = {}
Exception in thread "main" while scanning for the next token
found character '#' that cannot start any token. (Do not use # for indentation)
in 'reader', line 74, column 11:
name: #project.name#
^
org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:420)
org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:226)
org.yaml.snakeyaml.parser.ParserImpl$ParseBlockMappingValue.produce(ParserImpl.java:586)
org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:158)
org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:143)
org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:132)
org.yaml.snakeyaml.composer.Composer.composeMappingNode(Composer.java:229)
org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:155)
org.yaml.snakeyaml.composer.Composer.composeMappingNode(Composer.java:229)
org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:155)
org.yaml.snakeyaml.composer.Composer.composeMappingNode(Composer.java:229)
org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:155)
org.yaml.snakeyaml.composer.Composer.composeDocument(Composer.java:122)
...
Process finished with exit code 1
I realize that # is not a valid YAML character, just not sure how this was working in Eclipse and not in IntelliJ
Edit:
One thing that I left out of the original questions is that we have a multi-module project. It's the project's root pom that inherits from spring-boot-starter-parent that has this:
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/application.yml</include>
<include>**/application.properties</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
<excludes>
<exclude>**/application.yml</exclude>
<exclude>**/application.properties</exclude>
</excludes>
</resource>
</resources>
And in our project it is a submodule that is in need of the filtering. The application.yml file is in the correct location of the submodule and Eclipse did not seem to mind that it was a submodule. I know that Eclipse and IntelliJ treat multi-module projects a little differently (Eclipse has flat structure while IntelliJ is hierarchical).
Turns out that the resource filtering was working in IntelliJ. There was one property, #project.name# out of the four that was not being filtered correctly. Somehow this wasn't a problem in Eclipse. So we just removed that property from application.yml since we weren't using it.
Also, right-clicking on the pom.xml and selecting Maven then reimport seems to help with this. This especially helps if IntelliJ does not currently recognize yoru project as a Maven project.
It worked for me:
artifact: '#project.artifactId#'
Just kept the value within single quotes
Update intellij idea (to 2018.1.7 (build 181.5540.23)) helped in my case!
Adding quotes solves ?
from artifact: #project.artifactId# to => 'artifact: #project.artifactId#'
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
Adding above in pom.xml tag fixed the issue.
https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html