views:

1244

answers:

3

I have an eclipse project where every source folder has its own associated output folder. Instead of /classes it's called /eclipse-classes.

So if I have a folder: src/main/java (typical maven thing) the target folder is: target/eclipse-classes

And likewise for resources etc.

This seems to work (i.e. eclipse generates .class files that are put inside these folders) but running any Junit tests throws an exception stating "class not found". I'm running JUnit using the built-in eclipse test runner (i.e. right click the class, "run as", "Junit test").

Copying the /eclipse-classes folder to /classes makes them succeed, meaning eclipse is using /classes, but I can't find any configuration options to change it. Is there any way to find out where and why eclipse is still using the /classes folder?

(perhaps relevant, I'm also using the m2eclipse plugin)

Some additional information inspired by Rich Seller's answer: Maven is configured to run the following on resource changes:

process-resources resources:testResources

While this won't do anything useful (copies to the wrong directory) the resources are not problematic atm since they end up in the correct location.

The .classpath entries look okay. There's a bunch of maven subprojects so the nesting goes a bit deeper than what Rich posted, but otherwise it's exactly the same except for this line:

<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>

I think we might not need that one but it's not hurting anything atm.

edit2: Further testing reveals that eclipse is generating class files in both the /eclipse-classes folders and the /classes folder. It seems that m2eclipse is running mvn build in the background when building automatically, but I can't seem to find a way to disable this. I'll try to get in touch with the m2eclipse developers if nobody here has any other ideas.

+2  A: 

If you use m2eclipse, then the config in the Eclipse project is overwritten by the plugin. See this article for a solution.

The reason for this is that some maven plugins can't cope with a directory that is outside of target/, so the m2eclipse devs force the folders for compiled classes to be target/classes and target/test-classes, no matter what you configure in Eclipse.

By using a profile, you can use different folders for Eclipse. Still, it's not wise to change the output folders for maven (and its plugins).

Aaron Digulla
I don't think so, the eclipse compiler is outputting classes to the separately defined folders just fine. So the eclipse compiler is picking up on my output folders, it's the runtime classpath that is broken. I don't want maven to be in charge of generating those .class files as it's likely to break incremental compiling.
wds
Also, the solution mentioned seems to be geared at configuring maven to put its .class files somewhere else when eclipse is being used, so eclipse can use target/classes. I'm approaching it from the other side I guess: configuring eclipse to get out of maven's way. This seems like a more logical approach to me (not polluting the project .pom), but only if the junit plugin somehow uses the build path to create its runtime classpath.
wds
This work around fixed my classpath issue since moving from maven-eclipse-plugin to m2eclipse. Thanks for posting.
JamesC
+1 I think you were right about this bit for junit at least.
wds
@wds: "I'm approaching it from the other side" doesn't work since m2eclipse manipulates the classpath of Eclipse and the only way to undo this is by configuring Maven correctly (because the build settings from Eclipse will be partly ignored).
Aaron Digulla
@Aaron yes I've made everything use the same output folders now. It only gets it wrong (out of date classes) every once and again now.
wds
@wds: It breaks when you run maven from the commandline since Eclipse doesn't expect anyone to modify compiled project files (Eclipse only watches source files for modifications). That is why you should configure separate output folders. See the m2eclipse FAQ how to do this.
Aaron Digulla
+2  A: 

The Eclipse JUnit integration has no special classpath configuration, it will work off the output folders defined in your classpath and should find all classes compiled to those folders. It may be that there is something dodgy in your .classpath file, so that JUnit is confused (by default the .classpath file is hidden from view, it is located in the root of the project).

Based on your description I would expect to see entries something like below (note the default output folder and the override for src/main/java and src/main/resources). Does your classpath look markedly different, if so that may be the issue

<classpathentry excluding="**" kind="src" output="target/eclipse-classes" path="src/main/resources"/>
<classpathentry kind="src" output="target/eclipse-classes" path="src/main/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>


This is a long shot, but it may also be that a Maven clean is configured on your project, if that is the case the contents of target/eclipse-classes would be dropped whenever the clean goal is run, so your tests would be deleted from the file system before the tests are run. You can see what goals are run by Maven by opening the project properties (alt-enter) and selecting the Maven item.


This part doesn't directly answer your question, but you may find useful anyway. I tend to have my Eclipse output directories the same as for Maven and have no issues inside Eclipse (I modify the Maven builder to only run process-resources so it doesn't attempt to compile).

If I do a Maven build the Maven compiler will build any changed classes (that would be all of them if a clean is included). A subsequent modification in Eclipse is detected by the incremental compiler and processed, all is fine. I do turn off Build Automatically, but that's just because it annoys me, it may be that Maven and Eclipse fght if you have them both turned off.

Rich Seller
I'm pretty sure maven only runs process-resources. I'll try the rest on monday and get back to you.
wds
added some more info, don't see anything there that might explain it...
wds
I +1'd your post as eventually I just gave up and configured maven and eclipse to use the same output folders. It breaks very occasionally but I guess it's Good Enough(TM).
wds
A: 

Just in case you're open to trying a different plugin for this: I use the maven-eclipse-plugin to generate my Eclipse project settings. I configure the plugin to configure my Eclipse project to use a completely separate output directory for classes (see below). It's relative to the project root, so it sits outside of target.

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <version>2.6</version>
        <configuration>
            <outputDirectory>eclipse_build</outputDirectory>
        </configuration>
    </plugin>

This works great for me, including being able to run tests right out of the box, both via Maven and Eclipse.

dirtyvagabond