In Eclipse, how do I exclude test folder of one maven project from another project that has as a dependency? - eclipse

I have two maven projects imported into Eclipse in the same workspace. Both have a class with the same name and package, but different implementations and in different locations in each project. Let's call this class com.namespace.Factory
Project A has Factory under its test folder, i.e: /src/test/java/com/namespace/Factory.java
Project B has Factory under its main source folder, i.e: /src/main/java/com/namespace/Factory.java
There is also a Project C which is dependent on both. Project C also uses Factory from Project B for some of its unit tests. Problem now is Eclipse can't compile Project C because it can't differentiate between the two Factory classes. If I build all projects in command line, they don't have issues.
You would think that Eclipse would ignore the Project A Factory class since it is in test.
I am using the m2e plugin. My current work around is to setup m2e to not resolve Project C's dependencies within the workspace. This forces it to download the jar that will not have test in it. However, this means I have a change in either A or B, I have to manually install A or B push the latest jar to the local repo, and update Project C's dependencies to pull down the latest jars.
Is there a way to exclude the Project A test folder from the build path in Project C so that I can continue resolving everything within the workspace? It feels like Eclipse is breaking something that is fundamental to maven projects.

I think you're just another user affected by the upstream bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=376616
To sum it up, the bug report discussion includes:
JDT implements just one buildpath per Eclipse project. This is very unlikely to change, since this was fundamental design choice and many APIs and implementation details rely on that.
Well, but that doesn't really answer your question I guess.
So I see multiple options here, depending on how much influence you might have on the projects:
either try to rename one of the classes => names would be unique
or if the classes contain basically the same functionality, play with dependencies between projects, or even create new one, that the other 2 would depend upon
that's pretty much what comes to my mind right now

Perhaps you can try this:
In project A's Properties dialog (get there by right clicking the project and then click Properties),
click Deployment Assembly on the left.
Eclipse will show all source folders.
Select the test folder (/test) and click Remove.

Related

Include one project's jar libraries in another project depending on the first

I am working on two projects in Eclipse.
Project A depends on some jar files that come with the project, and those jar files have been added to the “Libraries” tab in Project A's “Java Build Path” property in Eclipse.
Project B depends on Project A, as well as directly using some classes in some of those jar files in Project A's build path.
I had assumed that adding Project A to Project B's Java Build Class would also add the jars already in Project A's build path, but that appears not to be the case.
Do I have to manually add those jars to Project B's build class, or am I overlooking a setting? If so, why is that a useful standard behaviour?
You have to manually add the jars to project B's classpath.
Adding a project dependency means project A depends on the compiled output of project B. Project B's output (its compiled .class files) doesn't contain the .jar files it depends on.
Why is this? I don't know the rationale of the eclipse authors, but my guess is that they want to keep the classpath as simple and verbose as possible. Things can get confusing if you have multiple versions of the same library on the classpath.
In vanilla java you can provide directory names for the classpath. When loading a class, the JVM will search these directories in order. Eclipse encourages a stricter approach where each jar is specified manually. Note that you can add multiple jars at once, so it's trivial to add all of project B's jars to project A's classpath.

Eclipse doesn't see classes from Maven modules in workspace

We have some Maven modules shared between several teams, with the mandate to share the source code even though our projects use different dependencies and resources. To accomplish this, we have our modules set up as recommended in Using Maven When You Can't Use the Conventions under "Producing Multiple Unique JARs from a Single Source Directory." Specifically, we have a shared parent module containing the src directory but whose pom declares <packaging>pom</packaging> and only builds the two submodules. Each submodule inherits from this parent and refers to the shared src directory using this:
<build>
<sourceDirectory>../src/main/java</sourceDirectory>
</build>
The two submodules have different artifact ids, allowing dependent modules and projects to specify which version and dependency set they need. It also upholds the Maven principle of "one module, one output."
This all works great in Maven-land: compilation, installation, deployments, etc. What doesn't work well is Eclipse integration. Some things work fine: building the modules, deploying to our Maven repo, pulling in dependencies to build our project. But things such as code completion and jumping to class/method definitions do not work at all. It's as though Eclipse doesn't recognize the source at all.
If we just check out a module from SVN, Eclipse doesn't know about the classes but instead uses jars from the repo. If we then import the modules as Maven modules, they show up in package explorer and the project build path. However, all references to those classes and methods are now flagged as errors by Eclipse. And we still do not have code completion or navigation.
So my questions are these: How can we get Eclipse to recognize the code and do its normal code navigation while still satisfying our varying project requirements? Am I missing some simple Eclipse configuration? Do we need to rework our Maven module structure, and if so, how?
Some additional context: The different dependencies for the projects are rather large, including different major versions for things such as Weblogic and Spring. The Weblogic versions will converge some time next year, but the other dependencies will be slower (and some resource files will likely always remain distinct). So for the near- to mid-future, we have to account for different dependencies between the projects.
We are using profiles to allow our Jenkins server to build both submodules while allowing individual developers to build only the submodule their project needs. Using profiles to manage the dependencies is problematic because we lose transitivity of dependencies.
Update (12/8/15)
I was eventually able to make Eclipse recognize the source directory by using "Link Source..." on the "Configure Build Path..." dialog. Adding a source folder would not let me reference the module's parent directory, but Link Source let me assign an arbitrary directory to use. It's not ideal, but it seems to be working.
I was eventually able to make Eclipse recognize the source directory by using "Link Source..." on the "Configure Build Path..." dialog. Adding a source folder would not let me reference the module's parent directory, which derailed me for a while. However,Link Source let me assign an arbitrary directory to use.
It's not ideal, but it seems to be working. We can now jump to definitions with F3, and errors are now highlighted correctly. It's good enough that I don't feel bad recommending it to the other team. I wish Eclipse would automatically allow a parent source directory to be referenced, but at least the manual intervention worked right.

Eclipse can't resolve transitive dependency projects?

In a Java project in Eclipse, I am trying to debug project A.
Project A has a dependency on B.jar, normally B.jar comes from my .m2/repository.
but now I want to make some temp changes to B's code, and have it reflected in A,
so I directly edit the source code in B project in eclipse, and set B as a dependency project in A's build path. Additionally, both A and B refer to C.jar as their dependencies.
This builds A fine, but when it is run, A's classpath contains 2 copies of all the classes and resources in C.jar. this creates a problem for those hibernate hbm.xml mapping files in C.jar and I got errors saying duplicate mapping for...
This looks to be a defect in eclipse, in that it lacks the resolution ability as maven posseses. is there a way to work around this? (apart from building B and installing to .m2 instead of having it as a dependency project)
Thanks
You mentioned "[setting] B as a dependency project in A's build path" - do you mean editing eclipse's build path or editing the project's POM? I'm guessing the former, in which case make sure that you have the latest version of the m2eclipse plugin installed and that both projects A & B are Maven eclipse projects. If it is set up correctly then your projects should look have an 'M' on their project icons, and the icons of any workspace dependencies should look like folders.

Working with Maven snapshots in Eclipse

If Project B has a dependency on Project A.
Do I need to do a maven install on Project A every single time I make a change to one of the classes in A in order for B to see the update?
It depends how you created the projects. If you have a common parent pom, then you won't need to run mvn install for one project to see the changes on the other.
If the projects don't share a common parent pom, I think it might be better to configure eclipse manually so it knows that B depends on A, and you'll also need to remove the dependency on the snapshot jar (otherwise you might get funky classloader errors). I have to say that every time that I had projects dependencies like this, the projects shared a common parent.

Eclipse + Subversion (subclipse) + Maven (m2eclipse) multi-module project

I have some related legacy projects that are a mess and I would like to mavenize them as a multi-module project shared on subversion (first multi-module project, we've always had them separate). There are a few key parts 1) webservice, 2) various swing clients, 3) model (w/ persistence from hibernate), 4) core JSE tasks.
I've been messing around for a few days trying to correctly set it up using Eclipse (Helios), Maven (2.2.1), m2eclipse (0.10.0) and Subversion (1.6) for our team. I keep stumping myself or having random errors that force me to backtrack. I'm hoping someone can help me out with some best practices.
Here are some of the questions:
m2eclipse requires a "flat" eclipse project structure. Does that mean I should create a subversion repository for each module? If I do one repository and try to check in from the parent project I'm having a difficult time setting the svn:ignore property on the nested project target (and other) directories.
If I do a module per repository, I seem to be able to check them in ok. The question then is what is the best way to check out via subclipse? Is there a best order? Parent or child project(s) first? Do I need to checkout the parent project and modify the checkout path of the children project to be nested in the file directory that will allow me to then "clean install" from the parent project?
Or, should I abandon subclipse and m2eclipse and checkout and run my maven goals from the command line.
Or, should I just be using the SCM integration with Maven. Or, maybe just not even try to get a multi-module project setup.
What do others do? Does anyone have some documentation (I missed) or some links (Google didn't recommend)?
Thanks in advance for your feedback.
m2eclipse requires a "flat" eclipse project structure.
Hmm, m2eclipse supports nested projects AFAIK (or at least importing a nested project structure). I don't use Eclipse wizards to create my projects though so maybe I'm not aware of something.
Does that mean I should create a subversion repository for each module?
No, no, absolutely not and I wouldn't do that (this will be hard to maintain). However, depending on your projects release cycles, you might have to think about the layout of your repository (single vs multiple trunk/tags/branches), especially if you plan to use the maven release plugin. If some pieces have independent release cycles, then I'd go for several trunk/tags/branches. If you always release them all together (as a single product), then a single trunk/tags/branches should do it. I wrote several answers on the topic that may be of interest:
Migrating to maven from an unusual svn directory structure?
Maven parent pom vs modules pom
How to handle maven versions in a multi module project?
If I do one repository and try to check in from the parent project I'm having a difficult time setting the svn:ignore property on the nested project target (and other) directories.
What is the particular problem?
If I do a module per repository, I seem to be able to check them in ok. The question then is what is the best way to check out via subclipse? Is there a best order? Parent or child project(s) first? Do I need to checkout the parent project and modify the checkout path of the children project to be nested in the file directory that will allow me to then "clean install" from the parent project?
Whatever choice you'll make (multiple repositories or not, multiple trunk/tags/branches or not), it should be possible to checkout the whole project structure in one time (using svn:externals if required). At least, you should try to make it possible (and it is, see the links posted above).
But I repeat, I do not recommend using multiple repositories (unless you want independent revision numbers) and nothing forces you to do that.
Or, should I abandon subclipse and m2eclipse and checkout and run my maven goals from the command line.
I use Eclipse, m2eclipse, subclipse successfully, all well integrated (at least for the build and "check in" part). But I do the initial import and the initial checkout on the command line and then imported
Or, should I just being using the SCM integration with Maven.
I don't use it, I don't have the need for it.
Or, maybe just not even try to get a multi-module project setup.
There is no reason to forbid the use of a multi-modules project setup, multi-modules builds are one of the key part of Maven.
What do others do? Does anyone have some documentation (I missed) or some links (Google didn't recommend)?
Have a look at the links I posted :)
It is a bit tricky at first. The way I've typically seen it setup is like so:
In subversion:
- Parent Project
-- Module A
--- pom.xml (module A)
-- Module B
--- pom.xml (module B)
-- Module c
--- pom.xml (module C)
-- pom.xml (parent project)
Some things to note (you already know):
You have to have the child projects
listed as modules in your parent
project
You have to list the parent project
in your child pom's (as the parent
group, artifact, version)
When you check out the project from
svn, you need to do 'check out as
maven project' instead of the
standard 'check out' (this one can be
a gotcha)
I hope this helps.