Git-Eclipse Peculiarities

When you clone (check out) a project that you're going to develop using Eclipse, it cannot be imported as a project unless it contains:

When changes are made to these files by Eclipse, as can happen (read on), then git status shows they are prime for committing. If you do this and the content being committed is specific to your development host, then that's not always helpful to others who will get your (sometimes irrelevant) changes the next time they pull from master. This article discusses best practice for these files (and subdirectory).

Beware

As long as you're working with a mixture of files that should—and others that should not—be tracked, you cannot blindly do

$ git add . $ git commit .

This will force tracking of files and subdirectories in an Eclipse project that have no business in the repository as discussed here.. Always use

$ git status

to show what is going to be added and committed if you do that. When you are tired of sorting through files and subdirectories in your git add commands to avoid committing what should not, add these to your .gitignore file.

.gitignore

This file isn't related to Eclipse, but it's useful in working around problems of the sort we're discussing here. Anyone that's used CVS or Subversion should understand immediately what this will do. Add a file or subdirectory to the list of names in .gitignore. That way, Git will ignore the fact that there's a new or changed file in the filesystem, won't show it in git status or complain that it needs to be committed.

.project

Simply put, commit this file to Git and share it, and any (rare) changes, to the repository.

It's possible to keep this file separate. Once upon a time, I collaborated in a work group that did this, but it was wrong-headed.

.classpath

If you use Maven, this file's contents are very less problematic. I don't use Maven.

Eclipse uses the .classpath file to "wire" up JARs used by a project, something that has been done using relative paths since Eclipse 3.5 (Galileo). The use of relative (workspace-relative) paths makes all the trouble with this file go away in terms of version-control systems.

Javadoc and/or source is another matter. This always involves full filesystem paths if you must go outside the project to add JARs (that is, in Eclipse's Build Path mechanism). This is specifically the case with Eclipse User Libraries, so don't use that handy mechanism.

This file contains information concerning a lot of really important things, but most of all, references to libraries.

So, first off, use either lib or WebContent/WEB-INF/lib in the project as a place to deposit all consumable (third-party or private, internal) JARs for the project. This works perfectly as long as you:

  1. Add any new JARs to that subdirectory*
  2. Use Build Path (Add JARs... button) to add them to the Libraries tab

This is because it's then stored as a relative path. In the wizards, just always ensure that you use the workspace options when you link JARs to sources or to Javadoc.

* Hint: Add JARs to a specifically (and fittingly named) subdirectory on this path in order to keep them sorted. It doesn't matter that JARs are subsumed by deeper directory hierarchy and it keeps them sorted at a glance. E.g.: all JARs shipped with Hibernate are kept in lib/hibernate (with the possible exception of one Apache Commons JAR left in a subdirectory named apache). Here's an example:

lib |-- apache | |-- commons-collections-3.1.jar | |-- commons-lang-2.6.jar | `-- log4j-1.2.16.jar |-- gson-1.7.1.jar |-- hibernate | |-- antlr-2.7.6.jar | |-- cglib-2.2.jar | |-- dom4j-1.6.1.jar | |-- hibernate3.jar | |-- hibernate-jpa-2.0-api-1.0.0.Final.jar | |-- hibernate-shards.jar | |-- hibernate-testing.jar | |-- javassist-3.12.0.GA.jar | |-- jta-1.1.jar | |-- oscache-2.1.jar | |-- proxool-0.8.3.jar | `-- slf4j-api-1.6.1.jar |-- jersey | |-- asm-3.1.jar | |-- jersey-client-1.6.jar | |-- jersey-core-1.6.jar | |-- jersey-json-1.6.jar | `-- jersey-server-1.6.jar |-- mongo | |-- mongo-2.6.3.jar | `-- morphia-0.99.jar `-- mysql |-- c3p0-0.9.1.jar `-- mysql-connector-java-5.1.16-bin.jar

Full paths in .classpath

You may have seen full paths in .classpath (and had to correct them using Build Paths). This happens when associating Javadoc and/or Java sources with various JARs. The dialog to do that results in recording a full path almost no matter what. Wiring JARs up to their sources or Javadoc is crucial for implementing Eclipse Content Assist (what's called "Intellisense" by Visual Studio).

Full paths in .classpath will render this file non portable, so committing it in Git will be very bad for your coworkers.

The solution to this problem is to be very careful about how you add source code or Javadocs. It's best not to commit any .classpath containing full paths because as soon as you do, you break anyone else pulling this change since the path is almost certainly not portable to his development host. So, once you start wiring JARs up like this, you're on your own.

Steps to adding source or Javadoc

Download, by preference, source and/or Javadoc JARs. This example uses them. Pure source code or Javadoc (HTML files) is not illustrated, though it's likely possible. This solution only works by keeping the third-party JAR inside the workspace project, i.e.: on a path like project-name/lib.

The example here is based on using Apache commons-configuration-1.7.jar and its accompanying source and Javadoc JARs, which I've downloaded to project TryStuff/lib/apache:

  1. Click Build Path -> Configure Build Path -> Libraries -> Add JARs... and add the library JAR from the project.
  2. Expand the newly added JAR to reveal Source attachment and Javadoc location options.
  3. For attaching source, edit, click Workspace button, navigate to the -source.jar and establish that JAR for source code.
  4. For attaching Javadoc, edit, click Javadoc in archive, click Workspace file radio button and navigate to the -javadoc.jar and establish that JAR for Javadoc.

This resulted in adding the following to .classpath, nothing of which constitutes a non portable, full filesystem path:

<classpathentry kind="lib" path="lib/apache/commons-configuration-1.7.jar" sourcepath="lib/apache/commons-configuration-1.7.sources.jar"> <attributes> <attribute name="javadoc_location" value="jar:platform:/resources/TryStuff/lib/apache/commons-configuration-1.7-javadoc.jar!/" /> </attributes> </classpathentry>

Eclipse Deployment Assembly and .classpath changes

This only affects Eclipse Dynamic Web Projects; it's not a problem for simple Java Projects.

Each time .classpath is changed, which happens when someone adds, deletes or changes a JAR library, just pulling an updated copy and pressing F5 (Refresh) will get rid of any JAR (missing symbol) errors or warnings. However, there will be a list of warnings about deployment. These must sometimes be be exorcized by right-clicking on the project, choosing Properties -> Deployment Assembly, selecting and removing the (simple) JARs from the list, then readding them (using Add -> Java Build Entries).

.settings

This is a subdirectory with configuration relevant both to the project and to the way users like to configure certain things in Eclipse. It's another place where Eclipse screwed the pooch a bit, but it's essential to track it because a lot of crucially important knowledge, like web-project facets, is kept there.

My approach is similar to that for .project: let the team lead define what's in here by creating a fully working project, commit it, then make changes to it and commit them, something that happens rarely, for everyone else to pull down.

An example of something that might change is what version of Tomcat is used. If experimenting with a different version than your colleagues, don't commit .settings until you're certain your colleagues should change too.

Other files and/or directories

Eclipse automatically creates subdirectories to hold class files compiled from .java sources, etc. These should never be committed since they're to be rebuilt by each developer locally. They include: