We have a problem at the place that I work with referencing multiple projects in our code. Basically, we have a product, which I'll call Leviathan. This project has quite a number of other versions, each of which we maintain as separate projects in Eclipse. As developers, we typically have multiple projects (multiple versions) open in Eclipse simultaneously, as we get helpline calls about older versions (as well as developing simultaneously multiple versions).
We also have test code, which is in a different project for each distribution of Leviathan. I name my projects Leviathan_<branch name>
. So, for example, in my Eclipse workspace, I might have projects like:
Leviathan_scott\ (my branch) Leviathan_9.2\ Leviathan_9.3\ Leviathan_10.0\ Leviathan_10.1\ Test_scott\ Test_10.0
My branch is a copy of our trunk, so we can consider that the most active development line.
The problem is that we reference some libraries in Leviathan\lib in our test code. Each developer may name their projects slightly differently. So, in developing the test project's .classpath, we reference the project Leviathan\ (no additions). The classpath for this project (which is checked into our source control system) might look like:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="**/*.MySCMServerInfo" kind="src" path="src"/>
<classpathentry kind="lib" path="lib/abbot-1.0.2/abbot.jar"/>
<classpathentry kind="lib" path="lib/abbot-1.0.2/costello.jar"/>
<classpathentry kind="lib" path="lib/dbunit-2.4.8/dbunit-2.4.8.jar"/>
<classpathentry kind="lib" path="lib/easymock-3.0/easymock-3.0.jar" sourcepath="lib/easymock-3.0/easymock-3.0-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/Test/lib/easymock-3.0/easymock-3.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="lib/objenesis-1.2/objenesis-1.2.jar"/>
<classpathentry kind="lib" path="lib/privilegedAccessor-1.0.2/privilegedAccessor_1.0.2.jar"/>
<classpathentry kind="lib" path="lib/unitils-3.1/unitils-core/unitils-core-3.1.jar" sourcepath="lib/unitils-3.1/unitils-core/src"/>
<classpathentry kind="lib" path="lib/unitils-3.1/unitils-database/unitils-database-3.1.jar"/>
<classpathentry kind="lib" path="lib/unitils-3.1/unitils-dbmaintainer/unitils-dbmaintainer-3.1.jar"/>
<classpathentry kind="lib" path="lib/unitils-3.1/unitils-dbunit/unitils-dbunit-3.1.jar" sourcepath="lib/unitils-3.1/unitils-dbunit/src"/>
<classpathentry kind="lib" path="lib/unitils-3.1/unitils-inject/unitils-inject-3.1.jar"/>
<classpathentry kind="lib" path="lib/unitils-3.1/unitils-mock/unitils-mock-3.1.jar" sourcepath="lib/unitils-3.1/unitils-mock/src"/>
<classpathentry kind="lib" path="lib/unitils-3.1/unitils-orm/unitils-orm-3.1.jar"/>
<classpathentry kind="lib" path="lib/unitils-3.1/unitils-spring/unitils-spring-3.1.jar" sourcepath="lib/unitils-3.1/unitils-spring/src"/>
<classpathentry kind="lib" path="lib/unitils-3.1/unitils-testng/unitils-testng-3.1.jar" sourcepath="lib/unitils-3.1/unitils-testng/src"/>
<classpathentry kind="lib" path="data"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/unitils-3.1/unitils-core/lib/ognl-2.6.9.jar"/>
<classpathentry kind="lib" path="lib/testng-5.14.1/testng-5.14.1.jar" sourcepath="lib/testng-5.14.1/testng-5.14.1-src.zip"/>
<classpathentry combineaccessrules="false" kind="src" path="/Leviathan"/>
<classpathentry kind="lib" path="/Leviathan/lib/slf4j-api-1.6.1.jar"/>
<classpathentry kind="lib" path="/Leviathan/lib/hibernate3.jar" sourcepath="/Leviathan/lib/src/hibernate-3.6.0-src.zip"/>
<classpathentry kind="output" path="classes"/>
</classpath>
When a developer loads the Test project into his/her individual Eclipse workspace, he/she would need to link the project to the original Leviathan project by going to Preference->Java Build Path->Projects and add the Leviathan_scott project.
The thing is, this of course doesn't change any of the <classpathentry ... >
entries that refer to "Leviathan\lib". So, we have to do one of two things:
Leviathan
to Leviathan_<branch name>
in my .classpath using a text editor find/replace.The problem with these is that it needs to be done every time the .classpath is changed, which makes both of these seem less than ideal. Our classpath isn't changed super-regularly, but I would say it's changed once or twice every two weeks. I'd like to be able to link my project and have to perform only a single step in order to link these projects.
It seems like we could set up an environment variable within Eclipse and add this into the .classpath entries. But, now we have a problem because if we have multiple Test projects in our workspace that we want to compile, this won't work. Both of the test projects' .classpath entries will refer to the same environment variable, which of course can only point to one super project location.
It seems like I should be able to do this, but I don't know exactly how to accomplish it in Eclipse. Any thoughts would be greatly appreciated.
~Scott
Try using Eclipse's 'Classpath Variables'.
Window->Preferences->Java->Build Path->Classpath Variables
Define one or more variables like "Leviathan_under_test" and point it to the version you want to test. Then, in the project build path, change the library reference to include the variable.
When you change the version of Leviathan you want to test, you change the variable and go. If you have to, you can even have multiple variables for versions that are tested more often, i.e. "LEVIATHAN_LATEST", OR "LEVIATHAN_PROBLEM_CHILD", etc.
This is a dependency management issue and there's lots of de-facto standard tools to help! I strongly suggest you utilise ANT with Ivy's dependency Managment or use Maven (or any otehr build tool that has dependency management).
With either of those I'd use a artifact repository maanger such as Nexus or Artifactory as well, so you have the one true source for your internally built artifacts.
This way you'll alway have the canonical version of the library that you want, when you want it.
If you don't want to use external tools to manage the various project dependencies you could try to go to the single Leviathan projects Build path property, in the tab Order and Export, and check the libraries you need to run your tests. in this way you don't need to import the libraries in the test project and by switching the project under test you automatically update the libraries
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With