How to set build paths automatically in Eclipse - java

Whenever I update our project's code from the svn I have to set the build paths of the libraries I import again because the last person who made a commit has a different classpath from mine.
Is there a way in Eclipse to automatically put in the imported libraries after updating from the SVN? I have heard of build files (Ant,Maven) but I really am not sure if I am looking at the right thing.

How about this: Don't commit local classpath files to the repository as ".classpath".
I don't mean to be a smartass, but it's ridiculous to allow people to check things in which break other developers' environments.

It is fine to not add .classpath/.project files if your project is simple and has few external dependencies. In practice you often have a number of relationships to maintain, so the overhead of making your .classpath portable is much less than the cumulative overhead of redefining it each time you bring the project into a workspace. The more involved your configuration, the more subtle errors you'll be fighting against attempting to reconstitute the project configuration.
You should be able to set up your classpath so it is portable by using Variables and Libraries, this avoids the need to hard-code paths. Your team can agree on a standard set of variables (and/or Libraries) to be used. A variable would then need to be defined on each developer's machine pointing to the common resources you use in your path.
Even better than Variables are Libraries. You can define custom libraries (under Window->Preferences->Java->Build Path->User Libraries) to reference your common components, then reuse those libraries in each project. A configured library can be exported from the User Libraries page and used by your peers.
Plugins such as m2eclipse provide Libraries (also know as Classpath Containers) that can automatically generate content based on some configuration (the Maven POM in m2eclipse's case). This abstracts the paths to underlying resources and allows multiple jars to be added to the path dynamically.
If you're not using Maven, the typical .classpath issue is that you want to add all jars in a folder to the classpath. This answer shows how it is possible to define a custom plugin to contribute all jars in a folder via a Classpath Container, you can also use this approach to automatically attach sources to the discovered elements and avoid having to repeat this effort each time.
Here is a typical before on the .classpath for a project I worked on recently. The library makes the configuration much lsess verbose, more portable, allows for reuse across projects, and defines the source attachments.
Before:
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/xml-apis.jar" sourcepath="C:/apache-ant-1.7.1/src/main"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant.jar" sourcepath="C:/apache-ant-1.7.1/src/main"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-antlr.jar" sourcepath="C:/apache-ant-1.7.1/src/main"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-apache-bcel.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-apache-bsf.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-apache-log4j.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-apache-oro.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-apache-regexp.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-apache-resolver.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-commons-logging.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-commons-net.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-jai.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-javamail.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-jdepend.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-jmf.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-jsch.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-junit.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-launcher.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-netrexx.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-nodeps.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-starteam.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-stylebook.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-swing.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-testutil.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-trax.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/ant-weblogic.jar"/>
<classpathentry kind="lib" path="C:/apache-ant-1.7.1/lib/xercesImpl.jar"/>
After:
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<!--all ant jars and source attachments defined here -->
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ant"/>

The maven dependency management and maven eclipse plugin would be one solution.
Once you have a running maven setup you can create the .project and .classpath files with the eclipse plugin. These files won't be checked in (all information is in the maven pom file).

Either don't check in classpath files, or use the same directory structure on each developer's machine.

Ant + Ivy is another solution. As far as I know there is no ivy -> eclipse task. We used ant + ivy in one of our projects and created the .classpath and .project files from the ivy metadata. (This was ivy 1.x maybe ivy 2 is capable to do this already.) This is analogous to the maven approach.

Related

remove absolute dependency path from `.classpath`; relative path doesn't work

I am not a Java programmer.
I did some Java programming in the past but nothing big.
There is one tool which I use, written in Java which I want to improve.
I got the sources of the tool.
I want to make a small change
(in how it parses input files, to add support for a different file format)
then compile the tool
upload updates to repository
end of story.
But first I have to be able to compile the original project.
I opened the project in Visual Studio Code.
I got errors
Project 'UVW' is missing required library: 'D:\xyz-workspace\java\_libraries\jfreechart-1.0.19\lib\jcommon-1.0.23.jar'
Project 'UVW' is missing required library: 'D:\xyz-workspace\java\_libraries\jfreechart-1.0.19\lib\jfreechart-1.0.19.jar'
Project 'UVW' is missing required library: 'D:\xyz-workspace\java\_libraries\gson-2.2.2.jar'
The project cannot be built until build path errors are resolved
Great,
the guy who did the tool added dependency to libraries on his own computer.
(here I replaced the project name with UVW and the author's name with xyz for privacy).
I check .classpath:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry exported="true" kind="lib" path="D:/xyz-workspace/java/_libraries/jfreechart-1.0.19/lib/jcommon-1.0.23.jar"/>
<classpathentry exported="true" kind="lib" path="D:/xyz-workspace/java/_libraries/jfreechart-1.0.19/lib/jfreechart-1.0.19.jar" sourcepath="D:/xyz-workspace/java/_libraries/jfreechart-1.0.19/source">
<attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="D:/xyz-workspace/java/_libraries/jfreechart-1.0.19/source"/>
</attributes>
</classpathentry>
<classpathentry exported="true" kind="lib" path="D:/xyz-workspace/java/_libraries/gson-2.2.2.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
So in the project directory I simply create the xyz-workspace, I replicate the structure and put there the missing libraries.
Then I edit the paths to be relative:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry exported="true" kind="lib" path="./xyz-workspace/java/_libraries/jfreechart-1.0.19/lib/jcommon-1.0.23.jar"/>
<classpathentry exported="true" kind="lib" path="./xyz-workspace/java/_libraries/jfreechart-1.0.19/lib/jfreechart-1.0.19.jar" sourcepath="./xyz-workspace/java/_libraries/jfreechart-1.0.19/source">
<attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="D:/xyz-workspace/java/_libraries/jfreechart-1.0.19/source"/>
</attributes>
</classpathentry>
<classpathentry exported="true" kind="lib" path="./xyz-workspace/java/_libraries/gson-2.2.2.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Ok,
but this still fails:
Project 'UVW' is missing required library: 'xyz-workspace\java\_libraries\jfreechart-1.0.19\lib\jcommon-1.0.23.jar'
Project 'UVW' is missing required library: 'xyz-workspace\java\_libraries\jfreechart-1.0.19\lib\jfreechart-1.0.19.jar'
Project 'UVW' is missing required library: 'xyz-workspace\java\_libraries\gson-2.2.2.jar'
The project cannot be built until build path errors are resolved
even though the paths are correct.
I tried to look online for how to do it correctly but found irrelevant results only.
I don't accept the situation that I replace the path on his computer with the absolute path on my computer.
I want the project be self dependent only, with all dependencies inside.
I don't know how to achieve it.
Apparently, I downloaded wrong version of the project.
In the new version, the libraries were already present in _libraries subdirectory.
The .classpath still contained absolute path to the directory inside the project.
But thus time editing it worked:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="lib" path="_libraries/gson-2.2.2.jar"/>
<classpathentry kind="lib" path="_libraries/ini4j-0.5.4.jar"/>
<classpathentry kind="lib" path="_libraries/jfreechart-1.0.19/lib/jcommon-1.0.23.jar"/>
<classpathentry kind="lib" path="_libraries/jfreechart-1.0.19/lib/jfreechart-1.0.19.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
The difference seems to be exported="true" from my original example.
This is an incomplete answer because I achieved the goal, I can compile the project without absolute path dependencies but I still don't understand everything.

Can I select different .jar files in an XML .classpath file depending on what OS I am building for?

We are building a Java tool that runs on both Windows and Linux. The project is built in Eclipse. In the project we include The Standard Widget Toolkit (swt.jar). There are no common swt.jar file for both Windows and Linux, so we have to use different files, and this is what is causing the problem. Some developers are building on Windows and some on Linux, and to make it work the developer have to change the swt file to match the current building environment and this has to be done in a number of places. This is one of the .classpath files:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry combineaccessrules="false" kind="src" path="/logviewer_common"/>
<classpathentry kind="lib" path="/logviewer/swt/linux_x64/swt.jar"/>
<classpathentry kind="con" path="SWT_CONTAINER/PLATFORM"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Is there a way to add a condition that if I am building on Windows the file /logviewer/swt/win64/swt.jar is included and if I am building on Linux instead the file /logviewer/swt/linux_x64/swt.jar is included?
I have been trying to read and understand the XML tags and found that there is an <os> tag where one can specify Windows or Linux(unix), but it seems like I am not clever enough to understand if or how this can be used.
It is configured and built with Ant.
Would be very grateful for some help!

Source Folder 'folder1' in project 'ProjectA' cannot output to distinct source folder 'folder2' in Eclipse

I am getting this error in some projects in my workspace.
I have tried using Luna and Juno version of eclipse but there are errors is still in there in both versions of eclipse
Content of .classpath file
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="folder1"/>
<classpathentry kind="src" path="folder2"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/WebSphere v6.1 JRE"/>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/com.ibm.ws.ast.st.runtime.runtimeTarget.v61/was.base.v61"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/hibernate"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/log4j"/>
<classpathentry kind="src" path="/ProjectB"/>
<classpathentry kind="src" path="/ProjectC"/>
<classpathentry combineaccessrules="false" kind="src" path="/ProjectD"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
<classpathentry kind="output" path="folder2"/>
</classpath>
There are no build path errors in ProjectB, ProjectC, ProjectD
There is no proper solution
You can change that issue from error to warning in project preferences.
Under Project Properties->Java Compiler->Building
Make Sure Enable Project Specific settings is checked, Under Build Path Problems,
change Output location overlaps source location from Error to Warning/Ignore.
You can also find some related discussion on the issue over here
I did get a solution on this issue:
There is a specification of which particular folder cannot be output at the time of creating the project. I renamed that folder to .old closing eclipse and , also tried deleting it as it was a sample folder.
If its a folder which is not that important rename that folder after closing eclipse and retry.
This would fix the problem.
For me the solution was to add this line
org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=ignore
to .settings/org.eclipse.jdt.core.prefs
You have to remove that the distinct source folder 'folder2' from the src path
GO to project build path
go to source tab
select the folder2 src entry
remove it

Use Eclipse classpath variable to replace absolute "sourcepath" path?

I would like to use an Eclipse classpath variable to resolve the attached source JAR file for a library in my classpath. This is the contents of my current ".classpath" file in Elcipse (Indigo):
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry exported="true" kind="lib" path="lib/ApacheCommons/commons-logging.jar"/>
<classpathentry exported="true" kind="lib" path="lib/Spring-WS/spring-ws-1.5.8-all.jar"/>
<!-- [other entries] -->
<classpathentry kind="output" path="bin"/>
</classpath>
When I now add a source JAR file for "spring-ws-1.5.8-all.jar", the ".classpath" files contents is:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry exported="true" kind="lib" path="lib/ApacheCommons/commons-logging.jar"/>
<classpathentry exported="true" kind="lib" path="lib/Spring-WS/spring-ws-1.5.8-all.jar"
sourcepath="D:/dev/sources/spring-ws-1.5.8-sources.jar"/>
<!-- [other entries] -->
<classpathentry kind="output" path="bin"/>
</classpath>
As you can see, Eclipse added the "sourcepath" attribute to the "classpathentry" element with an absolute path.
Now my idea is to replace the absolute path with the classpath variable "SOURCE_PATH", which is correctly set to "D:/dev/sources".
(Please, don't ask why we have this setup or suggest we must change it; it is an old project and we are unfortunately not able/allowed to change the build structure).
I tried
sourcepath="SOURCE_PATH/spring-ws-1.5.8-sources.jar"
as well as
sourcepath="${SOURCE_PATH}/spring-ws-1.5.8-sources.jar"
but both variants do not work.
I seems, that I either use the wrong syntax or I don't understand the concept of classpath variables. Maybe the classpath variable can't be used for the "sourcepath" attribute?
Thanks a lot for your help!
I might not understand your question completely but it sounds like you added your jar file with an absolute path to begin with. Instead add it with a classpath variable.
Use the Project properties, select Java Build Path option. Then click on the Libraries tab. Then Add Variable.... If you haven't created your SOURCE_PATH classpath variable yet, you can do it from here by clicking the Configure Variables... button (just a shortcut to the proper workspace preference setting). Once configured you should see your SOURCE_PATH class path variable in the box at the top. You can click on it extend to Extend... it to a subfolder or a jar file.
Using Tod's answer above, if you have lots of jars in lots of projects, you may find it easier to edit the .classpath files directly. Using a Java Build Path variable in .classpath changes the reference from:
<classpathentry kind="lib" path="/full/pathTo/Jar.jar"/>
to:
<classpathentry kind="var" path="NEW_PATH_VARIABLE/Jar.jar"/>
You could use a symbolic link. Windows also supports paths starting with /. This is drive dependent. Try cd / on the Command Prompt to verify.

Files and Folders appear in Eclipse inside the "Referenced Libraries" category. How to prevent this behavior?

I've inherited an Eclipse project in which a lot of the data is in the "Referenced Libraries" category, although for all good purposes they show up just as regular files / directories in the file system. Adding new files to the project yields a similar result -- they'll get thrown into the "Referenced Libraries" category.
I'd like to turn this weirdo-project into something more akin to the usual Eclipse java project experience, having Flasji's contents inside src/. How?
Edit ##:
Here are my .classpath file's contents as requested:
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="alloy4.2-rc.jar"/>
<classpathentry kind="lib" path="asm-2.2.3.jar"/>
<classpathentry kind="lib" path="bsh-2.0b4.jar"/>
<classpathentry kind="lib" path="commons-io-2.3.jar"/>
<classpathentry kind="lib" path="congu.jar"/>
<classpathentry kind="lib" path="Gent java6.jar"/>
<classpathentry kind="lib" path="junit-4.10.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
To get rid if these visually, open your MANIFEST.MF and in the editor click on the third tab "Runtime" on that editor page there is a classpath section and you will see the jars there, if you remove them in the editor your classpath will get auto updated and the referenced libraries will no longer exist.

Categories