I'm writing a test for a file parser class. The parse method receives a file name as parameter, and must open it in order to parse it ( duh ).
I've writen a test file, that I put into the test/resources directory inside my project directory, and would like to pass this file to test my parse. Since this project is in CVS, and will be manipulated by others, I can't hard code the file path, so I thought about use the maven ${basedir} property to build the file name in my test. Something like:
public void parseTest() {
...
sut.parse( ${basedir} + "src/test/resources/testFile" );
...
}
Does someone knows how could I achieve this?
You have 2 options:
1) Pass the file path to your test via a system property (docs)
In your pom you could do something like:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<systemProperties>
<property>
<name>filePath</name>
<value>/path/to/the/file</value>
</property>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
Then in your test you can do:
System.getProperty("filePath");
2) Put the file inside src/test/resources under the same package as your test class. Then you can get to the file using Class.getResourceAsStream(String fileName) (docs).
I would highly recommend option 2 over option 1. Passing things to your tests via system properties is very dirty IMO. It couples your tests unnecessarily to the test runner and will cause headaches down the road. Loading the file off the classpath is the way to go and that's why maven has the concept of a resources directory.
Related
I have a multi-module maven build where one of the child modules requires an extra goal to be executed as part of a release. But it looks as though any configuration of the maven-release-plugin in the child module is ignored in favour of the default configuration in the parent module.
This is the snippet from the child module. The plugin configuration is the same in the pluginManagement section of the parent pom, but without the custom element.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.1</version>
<configuration>
<tagBase>http://mycompany.com/svn/repos/myproject/tags</tagBase>
<goals>deploy myCustomPlugin:myCustomGoal</goals>
</configuration>
</plugin>
So is it possible for a child module to override the parent's configuration and add extra goals?
Maven version 2.2.1
Use combine.children="append" combine.self="override"
Parent POM
<configuration>
<items>
<item>parent-1</item>
<item>parent-2</item>
</items>
<properties>
<parentKey>parent</parentKey>
</properties>
</configuration>
Child pom
<configuration>
<items combine.children="append">
<!-- combine.children="merge" is the default -->
<item>child-1</item>
</items>
<properties combine.self="override">
<!-- combine.self="merge" is the default -->
<childKey>child</childKey>
</properties>
</configuration>
Result
<configuration>
<items combine.children="append">
<item>parent-1</item>
<item>parent-2</item>
<item>child-1</item>
</items>
<properties combine.self="override">
<childKey>child</childKey>
</properties>
</configuration>
See this blog for further details
Yes and no. Certainly a child pom can override the configuration of a plugin specified by its parent, and I have to assume you've done so correctly because there's nothing really hard about it. If you check the output of mvn help:effective-pom, you should be able to see plainly that this module has different settings for the release plugin.
The problem you're having is with the behavior of the release plugin. Typically, if you run a goal or phase--mvn compile, for example--from the root module of your project, it first runs that goal/phase on the root module, then on all the modules in reactor order, almost as if you'd run it in each module yourself. Any customizations you've added to child modules take effect as expected. When you run the release plugin, it runs only at the root module. It doesn't run in any of the child modules. Instead, running it at the root module forks a new build using the same settings as the root module, which runs for all the other modules in nearly the same way, except that it uses the root module's configuration for all the modules. I don't know the exact semantics, but I believe this is analogous to you manually running the release goals in each child and specifying the configuration options as system properties at the command line: regardless of how a child module configures the release plugin, the command line args win.
I've never dealt with this problem myself, and it's hard to say without knowing exactly what you're trying to accomplish. Perhaps if you can express what you want to do in this special module as a profile, then you could add a profile to your goals and or preparationGoals. Alternately, there's an arguments option to both the prepare and perform goals that you might be able to pull some tricks with.
I want to put the hibernate3-maven-plugin in my parent pom and have execution skipped in child modules if a given file does not exist in that module.
Is there any way to do this?
Up to now, I have had to do this:
<plugin>
...
<configuration>
<skip>true</skip>
<propertyfile>target/test-classes/jdbc.properties</propertyfile>
</configuration>
</plugin>
In the parent POM, and:
<plugin>
...
<configuration>
<skip>${maven.test.skip}</skip>
</configuration>
</plugin>
In all child POMs where I want it to execute. I.E Those actually having a jdbc.properties file.
You may be able to do this with profiles, but I suppose you'd probably not want to run it in the parent project, which may be problematic.
Here are some links on profiles:
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
http://www.sonatype.com/books/mvnref-book/reference/profiles.html
http://mindthegab.com/2008/12/02/howto-give-your-multimodule-maven-build-subprojectenvironment-specific-behavior/
This question, had a similar issue and was not able to solve it with profiles:
activate-different-maven-profiles-depending-on-current-module
I'm not 100% on the logistics but you could possibly use the maven exec plugin in combination with a shell script. The shell script would check for the presence of the file and then invoke the mvn plugin using the maven pom directory - which can be obtained and passed to the shell script via the Maven environment variables.
I have one main and one test config file which is shared by several maven projects. While testing, I am specifying the classpath to the directory where the test config file is.
This works fine if the whole project is tested/build but it doesn't work while running single tests. The config file is not found in the classpath.
here is the config:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<element>${project.parent.basedir}/conf/test</element>
</additionalClasspathElements>
</configuration>
</plugin>
any ideas why surefire ignores the property for running single tests?
thank you
Shouldn't it be:
<additionalClasspathElements>
<additionalClasspathElement>${project.parent.basedir}/conf/test</additionalClasspathElement>
</additionalClasspathElements>
put the config file in src/test/resources folder and try it .It should automatically be picked up. OR try to put under src/main/resources and use tag to point to that config file in the pom.xml of the project .Make use of 2.5 version of maven-surefire plugin.
If i define a plugin in the <build> tag and want to use this in my site command how do i do that? Do i have to define the plugin within <reporting> tag again?
And how about the configuration which i probably have done within the build tag and want to take place at the reporting tag as well? (i dont want to specifie for example a location of a configuration file twice just to use a plugin in 2 lifecycles)
As example: I define my checkstyle plugin in the build tag and configrue a custom location for the rules to be used. I do that because the rules are packed in a jar so i can define it as dependency. This would not be possible if i do it in the reporting tag. But i need to use this plugin in the reporting tag aswell so surfire can generate a report for checkstyle. So i have to define the plugin within the reporting tag aswell.
Maybe i'm doing something complete wrong here but i don't see how i can do it other then that. What i dont like is that i have 1 plugin twice in my pom (in the build tag and reporting tag).
I hope somebody can verify my solution is ok, or give me an advise how to do it better.
thx
kuku
A maven plugin is typically bound to execution in a given lifecycle phase when you define it. The plugin itself specifies which lifecycle phase this is, but you can change this if you have special needs.
If you have a multi-module build you can define a set of plugins with all parameters required in a common parent-pom. This will normally be executed for every sub-module in the build. If you do not want this to happen you can define it (in the parent pom) like this:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
... More plugin cofniguration stuff ...
</plugin>
If you in one or more nested moudules want to enable this plugin you can just say:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
... Maybe Configuration ....
</plugin>
In that specific module. You can choose if you want to reconfigure the default parameters which are inherited from the parent definition or not.
I think this is what you're looking for ?
In addition to KRosenvold's answer, you can also minimize configuration by declaring a plugin in the <pluginManagment> section, perhaps at your topmost pom in the inheritance chain, and then you can omit specifying the version of the plugin in all the other places you are declaring it's use.
Parent Pom:
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-1</version>
</plugin>
</plugins>
<pluginManagement>
Child Pom:
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>
I have a set of web apps that I manage that I am trying to move to maven.
/pom.xml // parent pom
webapp1/pom.xml // configured to point to parent
webapp2/pom.xml // peer of webapp1 and points to parent.
each of the webapps refers to the parent pom, and they both currently have a jetty maven plugin that works.
My question is how do I mount each of the webapps from the parent pom such that mvn jetty:run works in the parent directory?
edit to anwer: Pascal T
The issue is not so much that I'm getting an error when I try and run the command from the root pom, but that I'm not sure how to configure it.
for example the webapp1/pom.xml
looks like:
<project>
...
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
</plugin>
</plugins>
...
</project>
changing to this directory and typing mvn jetty:run works just fine and affords me the ability to hit: http://localhost:8080/webapp1.
However, what I would like would be to be in the parent of webapp1, and run all 'n' webapps from the parent directory. Thus having http://localhost:8080/webapp1, and http://localhost:8080/webapp2 available with one command line parameter.
btw, if the answer involved a tomcat plugin, that would be fine.
EDIT: I've totally edited my first answer now that I have a better understanding of the OP's expectations.
Check out Cargo, a thin wrapper that allows you to manipulate Java EE containers in a standard way.
Actually, there is a tutorial on Cargo's website that demonstrates how to use the Cargo Maven2 plugin to automatically start/stop a container (possibly deploying some deployables to it as it starts), which is what you're looking for from what I've understood.
I'm just not sure that doing this from the parent directory is feasible and if it's a requirement or if it would be ok to do it from another directory. I'll come back on this later. Lets first take a look at the Cargo Maven2 plugin setup.
In your case, you can start with the minimal configuration (that uses Jetty 5.x which is Cargo's default container):
[...]
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
</plugin>
</plugins>
</build>
[...]
If you want to use Jetty 6.x, you'll have to specify <containerId> and <type> in the <container> element:
[...]
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<configuration>
<container>
<containerId>jetty6x</containerId>
<type>embedded</type>
</container>
</configuration>
</plugin>
[...]
Then, add the modules you want to deploy by defining deployables explicitly inside the plugin configuration (refer to the Maven2 Plugin Reference Guide for the details of the configuration) :
<deployables>
<deployable>
<groupId>com.mycompany.myproject</groupId>
<artifactId>myproject-alpha</artifactId>
<type>war</type>
<properties>
<context>optional alpha root context</context>
</properties>
</deployable>
<deployable>
<groupId>com.mycompany.myproject</groupId>
<artifactId>myproject-beta</artifactId>
<type>war</type>
<properties>
<context>optional beta root context</context>
</properties>
</deployable>
[...]
</deployables>
With this, you should be able to start Jetty and have your webapps deployed on it with a simple (to run from the project containing the cargo plugin configuration):
$ mvn cargo:start
I'm just not sure that this can work with the parent pom (I wonder if this can lead to cyclic dependencies issues) and I didn't test it. But personally, I'd put all this stuff in the pom of a dedicated project, e.g. in a sibling project of your webapps, and not in the parent pom. I don't think it's a really a big deal and this is IMHO a better setup, especially if you plan to use cargo for integration testing.