Maven/Eclipse - Quick iteration acceptance Testing a project packaged as a WAR file - eclipse

Eclipse makes working with multi module maven projects easy because you don't have to re-build and re-install a module before dependent modules will see changes to it. So you just change the code and eclipse updates the dependencies magically in the background.
I want to achieve this behaviour for acceptance testing as well.
I have
storage-service
storage-service-war
storage-service-acceptance-tests
If I use embedded jetty or tomcat to test inside the storage-service-war project then obviously code changes are immediately viewable in the tests, but I cannot see any way to achieve the same quick iteration of testing when testing from storage-service-acceptance-tests.
Every way I look at it it seems that I have to build storage-service-war and then use the artefact generated from that, but it seems like overkill when you only want to change one line.
Does anyone have a good method for doing this?
Cheers
Piers

So answering my own question :D The solution I came up with will not work on CI it will likely only work when doing a local build as it makes use of the relative paths of the projects. At the bottom I outline a more robust but more complex approach that should satisfy eclipse and CI.
I was looking at setting attachClasses to true for the war plugin configuration of the war project.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
</plugins>
You can then reference the jar in the dependent project as follows
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>storage-service-war</artifactId>
<version>${project.version}</version>
<classifier>classes</classifier>
</dependency>
Then I was thinking I could run my tests from within the acceptance test module using embedded jetty or tomcat and pointing them to the web.xml defined in the war project using a relative path.
This works fine with maven via the commandline but fails in eclipse :(
The problem with this is that the jar produced by attach classes is not picked up by the eclipse m2e integration see -https://bugs.eclipse.org/bugs/show_bug.cgi?id=365419 unfortunately it wont be fixed.
So My solution for the moment is to manually add the storage-service-war project to my acceptance test project build path in eclipse. Its not great but it works
The above solution is a bit hacky but the alternative outlined is a bit more involved.
By splitting the project into the following I think it would be possible to have correct eclipse integration and projects that work on CI
storage-service
storage-service-core
storage-service-war
storage-service-acceptance-tests
storage-service-config
The core project contains the logic and source of the webapp and is of type jar, the config contains the web.xml and any other config files and is also of type jar. Then the acceptance-tests and war project are both of type war and serve merely to package the core project into a war and extract the config to the webapp/WEB-INF dir so that they may share a common setup.

Related

OSGi and Transitive Dependencies

I’m using Felix Framework for my OSGi project, but I’ve came across a severe problem concerning third party dependencies.
I’m using eclipse and maven-bundle-plugin to generate my bundles from the sources and the MANIFEST.MF from the POM.XML file. So far so good. however when I have some third party dependency in my bundle, I find myself looking for an infinite list of JARs, which usually are not bundles, and putting them in my /bundle Felix directory until no more dependencies are missing.
I call this process “Downloading the Internet for my OSGi application to work”.
What am I doing wrong? Sure I must be doing something very wrong, because I can’t imagine anyone having a bundle A that depends on B, which then depends on C and D, and then those two will depend on several others and so on… to go look for ALL those dependencies manually using google or maven central! That's insane!
What is the correct way to automate this? I would love to have one of the two solutions:
1) Be able to create a massive JAR file with all of its dependencies embedded, but exporting only the packages I want, and, of corse, not importing any package.
2) (My preferred solution) Having a way to get all my dependencies into individual JAR files that I can simply paste into the /bundle directory.
3) (Even more preferred) Having a way to use third party JARs without downloading 8GB of dependencies to my project.
I have found tools that do me this, but just for direct (1st degree) dependencies, leaving transitive dependencies for me to solve manually.
This problem is critical. The lack of such a tool hampers the usage of OSGi. I’ve searched and searched and searched, I’ve came across all the 101 solutions such as PAX, bndtools, and friends, but it seems that they do not solve this issue…
Please help me. Please provide a living example if you can, people like me around the world will benefit from the solution to this problem.
Thanks!
-
-
Edit: I am attaching a example project where I'm trying to use JScience but the resulting JAR bundle keeps asking me for new Imports, i.e., it is not self-contained.
Link to the example: https://www.dropbox.com/s/svo3nu3vawvv2xn/RequireJscienceExample.zip?dl=0
I usually try to convert 3rd party JARs into bundles using Eclipse, but they always have to Import packages that I do not have, so it is an endless situation as you have stated.
I could not find any documentation concerning the tag Conditional_Package for maven-bundle-plugin. However related searches show me the inline option that I have tried before without success.
I created a basic project where I have one class using JScience library, and in its POM.XML I have the following:
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId};singleton:=true
</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Export-Package>shared.properties.api, shared.properties.base
</Export-Package>
<Embed-Dependency>!org.osgi.*;scope=compile|runtime;inline=true</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
I am saying maven to inline all packages which are not from the osgi framework itself. And Looking at the resulting JAR it looks pretty good, I now have embedded only packages instead of entire JARs (however it looks to me that I didn’t need all those inlined packages since I’m using just two of them). Moreover, if I open the MANIFEST.MF file I can see this problematic line:
Manifest-Version: 1.0
Bnd-LastModified: 1414164534170
Build-Jdk: 1.6.0_65
Built-By: Pedro
Bundle-ManifestVersion: 2
Bundle-Name: RequireJscienceExample
Bundle-SymbolicName: RequireJscienceExample;singleton:=true
Bundle-Version: 0.0.1.SNAPSHOT
Created-By: Apache Maven Bundle Plugin
Embed-Dependency: !org.osgi.*;scope=compile|runtime;inline=true
Embed-Transitive: true
Import-Package: org.joda.convert,org.xml.sax <------ Problem...
Tool: Bnd-1.50.0
saying that I’m missing org.joda.convert and org.xml.sax.
What amazes me is that we are talking about a library (JScience) that states being OSGi compatible: http://jscience.org/
What am I missing? I really cannot afford not using JScience. And I have rejected several 3rd party libraries before, that would spare me development time, because of these OSGi 3rd party integration difficulties.
Why not just let Maven to resolve transitive dependency and download them for you.
Once you add them in pom.xml, IDE like Eclipse (m2e plugin actually) can already resolve, download and show resulted jars. (You can use mvn dependency:tree from command line as well)
Then review, and exclude unwanted, e.g. optional or with packages already exported by other bundle.
And yes, use provided scope e.g. for org.osgi.*
<Embed-Dependency>*;scope=compile|runtime;inline=true</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>

Eclipse and m2e - test classpath

I have Spring project backed up by maven and I am using m2e plugin. Now, some of my files are in the /src/main/webapp/WEB-INF/ folder. Now, the problem is that when I am running tests some of the .xml files with configuration don't work because paths to the resources are breaking.
Firstly, question. When I do on project Run As -> JUnit test, dose eclipse backs up by doing mvn test, or is it maven agnostic this way? If so this would explain why after adding
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>/src/main/webapp/</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
to my pom.xml when I run the test using Run As -> JUnit test and printing classpath I am not seeing my added location, but doing mvn test I can see this location added to classpath.
So, is it possible to make eclipse/maven copy some additional files to target/classes or target/test-classes
or
just add some folders to the runtime classpath when testing the applcation.
Also, is it possible to do such thing in one place so it does not matter if I am running tests using Eclipse gui or just mvn test from console.
Unless this has changed recently, your class path in eclipse is still built from your .classpath file.
m2e injects some elements, notably dependencies, but source/resource paths still need an entry.
Adding what you need to your .classpath should solve the issue.

Eclipse/Maven: JUnit tests not compiled when running them

I am working on a project using Maven and Eclipse (m2eclipse plugin). I've got problems with the JUnit tests:
Sometimes, when running them within Eclipse, they wont be compiled, but the old class files are used instead. When I delete the class files, I get ClassNotFoundExceptions in Eclipse. I then have to manually recompile them by using mvn test-compile or other goals.
I also noticed that the class files of the tests sometimes are put into the classes subdirectory instead of test-classes.
I really can't figure out what is wrong.
The JUnit java files are within src/main/java and are correctly named (*Test.java).
Do I have to compile and run them always via Maven? Why doesn't Eclipse compile the files when I want to run them? (Interestingly, sometimes it does. Sometimes everything works perfectly.)
I had the same problem with STS Eclipse (Spring development variant), m2e and JUnit. The solution was to set the output folder for src/test/java to target/test-classes:
Right click the src/test/java folder in the Package Explorer
Select Build Path -> Configure Output Folder
Enter target/test-classes, click OK
Now the changes in test classes are compiled correctly and you should be able to run JUnit tests in Eclipse.
The problem is that Eclipse compiles the unit tests to the default output folder target/classes while JUnit plugin correctly tries to run them from test-classes.
There are a few duplicates to this question:
ClassNotFoundException when running JUnit unit tests within Eclipse (using Maven)
Eclipse doesn't see my new junit test
junit not using the newest file
In addition to the answer below
Right click the src/test/java folder
Select Build Path -> Configure Output Folder
Enter target/test-classes, click OK
you should check to ensure that your builder is setup correctly by right clicking your project and going to Properties -> Builder. If you see that your builder is missing, you need to install one. In my case, the maven project had an AspectJ dependency and when I used the Maven Eclipse plugin to build my Eclipse project, it was looking for an AspectJ builder by default. I installed the AspectJ development tools and it solved the problem.
Hope this helps!
The most likely explanations for the problem you are facing is that the output folder of src/test/java is not correctly configured.
Instead of fixing this configuration manually, you can have m2eclipse fix this for you: Just right-click on the project and choose Maven > Update Project.
And another point: JUnit test classes should be in src/test/java, not src/main/java, otherwise they aren't detected correctly by Maven as test classes and they would be included in the packaged jar and not in the test jar.
I faced same issue. Tried above suggestions of configuring output folder & Maven>Update Project but neither worked. Finally changed my testOutputDirectory to "build/classes" as well and now Unit Tests are getting picked up and executed.
Finally found the reason for the issue. In my pom we had also configured maven compiler plugin as below
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<outputDirectory>build/classes</outputDirectory>
</configuration>
</plugin>
outputDirectory configuration is not needed and was the cause of above issue. After removing this tag, junits are getting compiled to build>testclasses folder and are being run during maven build as well. Yippee :)
Please check "testSourceDirectory" path which can be configured in your
pom.xml. And then, Add the folder (configured in "testSourceDirectory" path) to the eclipse build path.
Please find the sample "testSourceDirectory" in pom.xml below:
<build>
<testSourceDirectory>src/test/java</testSourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
Make sure that is there any exclamation mark on your project icon! In my case, i ignored that there is a exclamation point like:
exclamation point on project icon
Open the "Markers" perspective, then troubleshoot the problems according to the tips.
what the "Markers" perspective show
The junit test classes can be execute successfully after i called "mvn clean test" because they are not refer the unreadable jar which be warned in "Markers" perspective.Therefor, it's easily to ignore it..
For someone working on java-scala mix project, this is something to note.
Even after doing the configuration in the manner shown below,
<build>
<testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
<plugins>
...
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<testSourceDir>${basedir}/src/test/scala</testSourceDir>
<testOutputDir>${basedir}/target/test-classes</testOutputDir>
</configuration>
</plugin>
</plugins>
</build>
and doing a Maven > Update Project, eclipse honours the output directory of the src/test/java folder in the project, however, not for the src/test/scala folder. (You can figure this out by right-clicking on the specific source folder and choosing Build Path > Configure Output Folder... which should display the location as specified in the pom for the former case, however, not for the later case.
This is already a known bug for using scala with m2e as mentioned here: http://scala-ide.org/docs/tutorials/m2eclipse/
Warning
As of March 2013, a bug causes both src/main/scala and src/test/scala to use the default output folder (target/classes). This may be confusing >when building tests, since their class files will not end in target/test-classes, as they would when building on the command line. You can work around this by manually changing the output folder for src/test/scala.
Eclipse is not expecting anything else to be mucking with the class files. It assumes that if you haven't editted the file in eclipse it hasn't changed and doesn't need compiling. I think the issue stems from eclipse and maven sharing an output directory. I've often seen this if my mvn build fails, it will have deleted the class files as part of the clean but not compiled new ones. I think the best solution would be to have seperate build dirs for mvn and eclipse, but I've never look into this.
My problem wasn't the JUnit plugin but rather the configuration in my pom.xml.
After reviewing all the answers to this question, #Gulats's answer implied to me that I should try setting a testOutputDirectory in my maven-compiler-plugin section, and that did the trick:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<testOutputDir>${basedir}/target/test-classes</testOutputDir>
</configuration>
</plugin>

How to add a jar to the server lib for *embedded* JBoss?

I need to add a crypto provider to the embedded JBoss used by Seam for integration tests.
For the regular JBoss it's a simple matter, just drop the files into the /lib folder of the server instance. With the embedded JBoss, however, things seem to be different. I've tried putting the jars in /embedded-jboss/bootstrap/lib and /embedded-jboss but no change, the classes are not seen.
I've read http://community.jboss.org/wiki/EmbeddedAndJavaSE and also looked in the source of org.jboss.embedded.Bootstrap but I haven't found a way yet. The build is done with Maven if it matters.
Thanks a lot for any suggestions.
I found an answer in the meantime: they can be added to the classpath of the plugin that runs the tests, like below. Works for me.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- snip -->
<additionalClasspathElements>
<additionalClasspathElement>add/here/your/jar</additionalClasspathElement>
</additionalClasspathElements>

Getting Jetty & Maven to work form TextMate

I often work in Eclipse, but recently switched to TextMate, which is, in my opinion, the best text editor out there, barring perhaps VIM or something like that (but I find the learning curve too steep to jump into that quite yet).
The disadvantage is I don't really know how to run Maven & Jetty w/out using Eclipse. The engineers at work here set up Java projects that have POM files, etc. And it all runs fine in Eclipse, but I thought I heard somewhere that TextMate actually had a bundle somewhere to use Maven with, and I wondered if such a thing might include Jetty too.
I'm a UI guy, so please, keep the technical jargon down just a tad. (In other words, I don't do Java, though I understand some of it.)
You don't need anything fancy to run a Mavenized webapp on Jetty. Simply add the following snippet to your pom.xml (assuming your project has a packaging of type war as illustrated below):
<project>
...
<packaging>war</packaging> <!-- this is the packaging for a webapp -->
...
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.22</version>
</plugin>
...
</plugins>
...
</build>
</project>
And just run the following command in a console:
mvn jetty:run
Just in case, there is a Maven bundle for TextMate allowing to invoke Maven from TextMate. You can check this mail for details.