Executing a single test in an installed maven jar - java

I have a jar installed in my local ~/.m2 repo and I would like to execute a single test using the -Dtest option via a python script. I tried using this command on the command line mvn surefire:test -DdependenciesToScan=groupId:artifactId -Dtest=NameOfTest, however it doesn't seem like maven is finding the NameOfTest in the groupId:artifactId dependency and returning back with no tests executed? Any way to execute a single test in an already installed maven artifact?

Typically Java classes in src/test/java (or your corresponding test sources directory) will not end up in a built artifact by maven by default. If you inspect the contents of the JAR, you will likely notice no compiled test classes, which is why maven can't find them.
If you really want your test source compiled into the JAR, there are plugins to help you. Particularly, the standard Maven JAR Plugin.
However, I would suggest you consider carefully why you need test classes in a built artifact. The standard use of test suites is to test the main source code being built. There are some situations that have been argued where having tests in the final artifact are valid, but they are rare and usually can be worked around in other ways ( Related discussion ).

Related

Using maven to create junit xml reports of jar

I have inherited a codebase whereby we have a maven project of component tests that use junit as the framework that runs the tests.
Everything runs OK, but the problem is that these tests must be compiled into a jar-with-dependencies so that they can be run on a standalone computer with very limited outwards connectivity (e.g does not have access to maven central).
I have managed to create a runnable jar with dependencies which I can run using junit.jar and the command line like so:
java -cp jar-with-dependencies.jar:junit.jar junit.jar org.junit.runner.JUnitCore com.testsuite.AllTests
This works but the problem is that I also need to output the junit results into XML, like maven's surefire plugin does.
My question is, can I run this jar-with-dependencies using maven such that it creates the junit xml reports?
I can successfully run the tests using exec-maven-plugin which essentially runs the previously stated command

Should the mvnw files be added to the repository?

When creating spring-boot projects by using start.spring.io, some maven wrapper files get included:
mvnw
mvnw.bat
Should these files be ignored when committing to a git repo?
A mvnw Maven wrapper script allows you to run a Maven command without having Maven installed and present on your PATH. It does by looking for Maven on your PATH and, if not found, it downloads and installs Maven in a default location (your user home directory, IIRC).
They are a convenience but they are not necessarily part of your project, not in the same way as your project code and configuration is. In other words:
Any given mnvw file could be used for multiple, unrelated projects
A mnvw file will almost certainly not be different from one version of your project to another
On this basis you could make a case for not committing mvnw to your code repository.
However, including a mvnw script in your repo does have these benefits:
Allows anyone who clones / checks-out your repo to build your project without having to install Maven first.
Ensures that the version of Maven in use is the version with which your project is compatible.
On this basis you could make a case for committing mvnw to your code repository.
So, there are pros and cons on both sides. Just choose the side which best fits the needs of those who will use your repo. Either:
Include something in your readme which makes clear that (a) Maven is a prerequisite and (b) which version of Maven is required.
... or:
Include a mvnw script.
It depends, if you want to use the Maven wrapper or not. If not, then you can delete those files. If you want to use it, then you have to commit the files in the repository, otherwise it doesn't make sense to use it.

How to modify the Eclipse Run Configuration classpath?

I'm developing a project in Eclipse JDT, that has optional dependencies on OSGI - that is, it supports being used as an OSGI bundle, and if it is used as a bundle inside an OSGI environment, it will also reference some classes from OSGI.
Now I want to write JUnit test cases for both running inside OSGI and running without OSGI, included in two different test suites. The OSGI tests are run as JUnit Pulg-in Tests and the Non-OSGI tests should be run as normal JUnit Tests.
Now I have the problem, that I couldn't find any way in Eclipse to exactly specify the classpath for the JUnit Test Run Configuration and exclude the optional OSGI jars.
Is there any way to exclude jars or modify the default classpath for an Eclipse Run Configuration?
If not, does anyone have a suggestion, how one should setup JUnit tests in such a case?
The only solution I was able to find is, to create a jar file from my unit tests and run the tests without OSGI from a different project with the test jar file on the classpath. But I would prefer a more elegant solution, ideally without the necessity of a second test project.
With the help of Gimbys comment, I was able to solve the problem. Although it is not possible in Eclipse to modify the default classpath generated by JDT, it is possible to entirely remove the default classpath and then add your own classpath in the classpath tab of the Runtime Configuration.
To remove the default classpath, one has to select the root entry that is named after the currently run project, and then click on the "remove" button. After that one can add all the jar files and projects that should be loaded in the classpath. The downside of this approach is, that jar files, that are normally provided by Eclipse plugins like e.g. junit.jar, must then also be selected manually (e.g. by adding it to a library folder of the project or by selecting the external jar in the plugins directory of the Eclipse installation folder).
I would suggest that you split up your project in 4 separate projects:
Logic: This package contains all the logic, so basically what your program/plug-in does
Logic.plugin: This Project resembles a Plugin-Project (OSGI-Bundle). This project contains only configurations needed for your plugin and everything dependent on osgi. It has a dependency on your Logic Project.
Logic.plugin.test: All the test cases for your osgi bundle. It is the normal plugin approach to split up logic and test cases
Logic.cli: This project contains the command line interface (or whatever your alternate application is). This also depends on the Logic project.
If your CLI project is only very small you may merge it with the Logic project.

Running a Maven project with many dependencies

I'm hacking on a Maven-based project with a lot of dependencies; the project is normally meant to be developed in Eclipse but I need to work on it from the command line.
How to build+execute the project in a sane way? Something like mvn run, but of course Maven is not meant for running Java projects (for some reason).
The problem is specifying all the dependencies on java's commandline, I don't even know how to autogenerate that. I can currently deal with it using the assembly:single maven plugin (using the jar-with-dependencies descriptor) which will package the dependencies to a single .jar for me.
However, there really is a lot of dependencies and the assembly phase can take about two minutes, greatly disrupting my hack-test cycles so I'm looking for other ways to run the project with minimum build overhead - any recommendations, please?
Note: One possibility is running it in Eclipse once and capturing the java commandline. However, that's just a one-time hack, not a general solution in case I change pom.xml later or come to another project from the suite without Eclipse access anymore.
Have a look at the maven exec plugin
mvn exec:java -Dexec.mainClass="com.example.Main"
if you do this frequently, you can of course configure it via plugin configuration.
Regarding finding out project dependencies - you can use maven dependency plugin
http://maven.apache.org/plugins/maven-dependency-plugin/list-mojo.html
If you want to put them into file it'd be smth like
mvn dependency:list > dependencies.txt
See this question: How can I create an executable JAR with dependencies using Maven?. You can use the dependency-plugin to generate all dependencies in a separate directory before the package phase and then include that in the classpath of the manifest.
I see three solution to this:
onejar-maven-plugin - faster than assemlby with jar-with-dependencies descriptor
With onejar-maven-plugin, you'll (...) get a nice clean super jar with the dependency jars inside.
Spring Boot Maven Plugin - but this is dedicated to Spring projects
Maven Assembly Plugin with custom descriptor. This custom descriptor should grab all dependencies into lib folder, maven-jar-plugin should set Class-Path in Manifest.fm according to this new location. After this you can simply execute your program or zip your jar with lib folder as distribution.
After this is possible to run your program on your computer or any other with one command:
java -jar myjar.jar

Using maven to produce production ready output

I have a muti-module maven project, and I created a new module that depends on 3 other modules. (I already have a web app maven module that produces a .war file, now I need this)
This module's output is a .jar, and it has a few resources also which are:
spring context xml file
properties file
Now I want to produce a production ready folder so I can upload it to my server. I am hoping maven can do this for me.
I need the following layout:
myjar.jar
/libs/ (the 3 other maven modules that are dependancies)
/resources
Also, there are some generic dependancies that my parent pom.xml have like slf4j/log4j/ that I also need to package.
It would be cool if I could add a switch to mvn that will produce this like:
mvn clean install production
I plan on running this on my server via the command line.
I think what you are looking for is a Maven Assembly:
https://maven.apache.org/plugins/maven-assembly-plugin/
You can use profiles to disable the generation of the assembly by default (can speed up the development process).
#puce is right in that you may be best to use the Assembly Plugin. What you can't do easily is add another lifecycle 'production' to maven. If you have time you could write a plugin to do this, but you might be better off using a profile called 'production' or 'prod-deploy' to enable the coping into place on the server.
mvn clean install -Pprod-deploy
One thing to remember with maven is that it is very good at building projects in using it's conventions, but it is pretty bad at actually script things to happen out side of the build lifecycle.
I have on several occasions used external scripting tools such as ant/python/bash and groovy to first run the build using mvn then to script the deployment in a more natural language.
The intention of Maven is building not deployment in the sense to production. For this purpose i would recommend things like Chef or Puppet. From a technial point of view it's of course possible to handle such things via Maven. What also possible to build on CI solution like Jenkins. Furthermore it's possible to run a script from Jenkins to do the deployment on production.

Categories

Resources