3

I share an Eclipse project between three different machines using Dropbox. Now the problem is that the paths in the .classpath file are not the same on all machines. I tried to replace /Users/username with ~ but that does not work. However, that file is synchronized by Dropbox on the different machines which leads to problems.

Is there a way to configure the name and/or path of that .classpath file on a per-project base?

PS: This is NOT about version control. I know and use it for this project, but I need a solution to work without version control.

The directory structure is as follows

  • .metadata (excluded from syncing)
  • src (version controlled)
    • .classpath
    • my other files

The .classpath file is generated by the sbt eclipse command. Currently, it looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" output="target/scala-2.10/classes" path="src/main/scala"/>
    <classpathentry kind="src" output="target/scala-2.10/classes" path="src/main/java"/>
    <classpathentry kind="src" output="target/scala-2.10/test-classes" path="src/test/scala"/>
    <classpathentry kind="src" output="target/scala-2.10/test-classes" path="src/test/java"/>
    <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/com.typesafe.akka/akka-actor_2.10/bundles/akka-actor_2.10-2.1.0.jar" sourcepath="/Users/USERNAME/.ivy2/cache/com.typesafe.akka/akka-actor_2.10/srcs/akka-actor_2.10-2.1.0-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/com.typesafe/config/bundles/config-1.0.0.jar" sourcepath="/Users/USERNAME/.ivy2/cache/com.typesafe/config/srcs/config-1.0.0-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/com.typesafe.akka/akka-remote_2.10/bundles/akka-remote_2.10-2.1.0.jar" sourcepath="/Users/USERNAME/.ivy2/cache/com.typesafe.akka/akka-remote_2.10/srcs/akka-remote_2.10-2.1.0-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/io.netty/netty/bundles/netty-3.5.8.Final.jar" sourcepath="/Users/USERNAME/.ivy2/cache/io.netty/netty/srcs/netty-3.5.8.Final-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/com.google.protobuf/protobuf-java/jars/protobuf-java-2.4.1.jar" sourcepath="/Users/USERNAME/.ivy2/cache/com.google.protobuf/protobuf-java/srcs/protobuf-java-2.4.1-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/org.uncommons.maths/uncommons-maths/jars/uncommons-maths-1.2.2a.jar" sourcepath="/Users/USERNAME/.ivy2/cache/org.uncommons.maths/uncommons-maths/srcs/uncommons-maths-1.2.2a-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/com.esotericsoftware.kryo/kryo/jars/kryo-2.20.jar" sourcepath="/Users/USERNAME/.ivy2/cache/com.esotericsoftware.kryo/kryo/srcs/kryo-2.20-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/com.esotericsoftware.reflectasm/reflectasm/jars/reflectasm-1.07-shaded.jar" sourcepath="/Users/USERNAME/.ivy2/cache/com.esotericsoftware.reflectasm/reflectasm/srcs/reflectasm-1.07-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/org.ow2.asm/asm/jars/asm-4.0.jar" sourcepath="/Users/USERNAME/.ivy2/cache/org.ow2.asm/asm/srcs/asm-4.0-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/com.esotericsoftware.minlog/minlog/jars/minlog-1.2.jar" sourcepath="/Users/USERNAME/.ivy2/cache/com.esotericsoftware.minlog/minlog/srcs/minlog-1.2-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/org.objenesis/objenesis/jars/objenesis-1.2.jar" sourcepath="/Users/USERNAME/.ivy2/cache/org.objenesis/objenesis/srcs/objenesis-1.2-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/ch.ethz.ganymed/ganymed-ssh2/jars/ganymed-ssh2-build210.jar" sourcepath="/Users/USERNAME/.ivy2/cache/ch.ethz.ganymed/ganymed-ssh2/srcs/ganymed-ssh2-build210-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/commons-codec/commons-codec/jars/commons-codec-1.7.jar" sourcepath="/Users/USERNAME/.ivy2/cache/commons-codec/commons-codec/srcs/commons-codec-1.7-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/junit/junit/jars/junit-4.8.2.jar" sourcepath="/Users/USERNAME/.ivy2/cache/junit/junit/srcs/junit-4.8.2-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/org.specs2/specs2_2.10/jars/specs2_2.10-1.13.jar" sourcepath="/Users/USERNAME/.ivy2/cache/org.specs2/specs2_2.10/srcs/specs2_2.10-1.13-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/org.specs2/scalaz-core_2.10/jars/scalaz-core_2.10-7.0.0.jar" sourcepath="/Users/USERNAME/.ivy2/cache/org.specs2/scalaz-core_2.10/srcs/scalaz-core_2.10-7.0.0-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/org.specs2/scalaz-concurrent_2.10/jars/scalaz-concurrent_2.10-7.0.0.jar" sourcepath="/Users/USERNAME/.ivy2/cache/org.specs2/scalaz-concurrent_2.10/srcs/scalaz-concurrent_2.10-7.0.0-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/org.specs2/scalaz-effect_2.10/jars/scalaz-effect_2.10-7.0.0.jar" sourcepath="/Users/USERNAME/.ivy2/cache/org.specs2/scalaz-effect_2.10/srcs/scalaz-effect_2.10-7.0.0-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/org.specs2/classycle/jars/classycle-1.4.1.jar" sourcepath="/Users/USERNAME/.ivy2/cache/org.specs2/classycle/srcs/classycle-1.4.1-sources.jar"/>
    <classpathentry kind="lib" path="/Users/USERNAME/.ivy2/cache/org.mockito/mockito-all/jars/mockito-all-1.9.0.jar" sourcepath="/Users/USERNAME/.ivy2/cache/org.mockito/mockito-all/srcs/mockito-all-1.9.0-sources.jar"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
    <classpathentry kind="lib" path="/Users/USERNAME/Downloads/Java-WebSocket-master/dist/java_websocket.jar"/>
    <classpathentry kind="output" path="bin"/>
</classpath>
18
  • well, you should not use absolute file paths. Put all of your dependencies into a Simple Project, then add workspace references. Commented Feb 2, 2013 at 15:23
  • I updated the question with mentioning that I am using sbt which creates this .classpath file. So far, I was not able to find a way to configure it differently. Commented Feb 2, 2013 at 15:44
  • That's what SCM are used for... Commented Feb 4, 2013 at 15:17
  • ...and build tools like maven (or even a properly configured ant, but that is harder to do correctly). Commented Feb 4, 2013 at 15:42
  • @nico_ekito Did you read my "ps"? We use SCM but I have to change computers often and can't check in code that is work in progress and might break things. This would also make the version history unncessery complex. Commented Feb 4, 2013 at 16:08

5 Answers 5

1
+50

I'm not familiar with sbteclipse, but according to their wiki page, running sbt eclipse will generate the .classpath file. The way you're running it, it's generating absolute paths for your dependent libraries, which you don't want.

There is a setting called relativizeLibs that looks like it's the problem. You should set that to true (which is apparently the default value). You will then likely have to make sure you run sbt eclipse from the same relative location to the project and library files on each computer, but you should be able to make that structure consistent between your development machines.

Sign up to request clarification or add additional context in comments.

7 Comments

Looked promising but apparently that setting does not influence the .classpath file in any way.
@str Note that the relativizeLibs docs refer to another setting retrieveManaged := true which I don't see documented at all. Perhaps try setting that as well?
I tried that already but it has no influence on the paths either. Thanks for trying to help.
@str looks to me like a bug in sbt eclipse then... good luck.
@str have you looked at classpathTransformerFactories? I'm just going on the docs here, but I would imagine that you could use that to convert those absolute paths to relative ones...
|
1

The first solution that really seems to work so far is a little ugly but very easy. I just created a symbolic link in the /Users/ directory to make Eclipse find the needed files.

cd /Users/
sudo ln -s USERNAME-ON-THE-CURRENT-MACHINE/ USERNAME-IN-THE-PATH-OF-THE-CLASSPATH-FILE

That way I can easily share code between my different machines.

And a note on version control: Yes, we use version control. Actually, we work on a Github fork of a University project with a lot of pull requests, branches and several developers. So the Dropbox solution is not a substitution for an SCM. However, it helps me to be very flexible in changing between different computers quickly and I do not have to handle branches, commits and so on just to keep the files up-to-date. But of course, all changes are committed to Github when they are ready.

1 Comment

As you already use Git, you might want to think about sharing an empty Git-Repository clone over Dropbox rather than your working project. Then you can work with branches you won't commit to your central repository and benefit from both, constant version control and carefree committing even if not all of your files compile...
0

You can remove the binaries folders from dropbox, by doing so everytime dropbox synch it only overrides your code, and eclipse will have to build again , and the problem should be solved.

1 Comment

Not really. I already exclude the binaries but Eclipse places the .classpath file (files can not by exluded from syncing in Dropbox) in the root of the version controlled source folder and I can't exclude that one ;)
0

There is no way to rename the .classpath file, it's one of the very few things that Eclipse needs to be hard-coded in order to work (it, along with the .project file are the bootstraps by which Java projects are managed; Eclipse JDT has to inherently "know" where those files are).

I don't know anything about sbt, but in general there are several capabilities/techniques in Eclipse Java projects to keep .classpath clean (free from absolute or machine-specific paths). In a typical Java project, the user makes changes to the Project via the Build Path properties which result in changes to .classpath; does sbt re-generate that file periodically? Can you post the contents of your .classpath?

3 Comments

I added the content of my .classpath file to the question. I am not sure whether it gets regenerated by sbt but I don't think so.
Wow, that's truly awful .classpath. There are ways to clean it up (ie, remove the absolute paths) but it would be a bit of work and it doesn't solve the problem of sbteclipse generating such a beast in the first place.
It seems like @sharakan is onto something. Even if sbteclipse can't be configured to avoid such absolute paths for external libs, a feature request should be opened against it so that the developers are aware that they aren't generating a .classpath that plays nice in a multi-developer or multi-machine situation.
-1

Although your probably not going to do this given you have already answered the question... you really should not:

  • Checkin .project and .classpath files
  • Share projects files across different computers instead of using SCM (particularly since your using Git).

I believe Ivy, Gradle, SBT, and Maven all have solutions for managing .classpath and .project. You should investigate those options. Also Eclipse has both a Maven and Ivy plugin (http://ant.apache.org/ivy/ivyde/) which will automatically manage your your classpath for you based on the Ivy and Maven file.

As a developer that works on many other projects is rather annoying when some one checkins .project and .classpath. Sharing outputted files across different machines (.class and .project, .classpath) is also dangerous. Thats because you could have different versions of Eclipse and different JDK compilers not to mention Eclipse partially compiles Java files. It may work for you now but its a hack.

Also as I noted in a comment you'll either have to remember to refetch ivy dependencies or include those in your sync (ie your .ivy2 directory which can be absolutely massive) and since you'll have to remember to refetch ivy dependencies are you that lazy to not regenerate your .classpath (unless SBT is completely lacking on that) ?

5 Comments

We do not check in any .project or .classpath files. The only file that is shared on my machines only is the .classpath file. I know that my solution is a "hack" but no other suggested solution comes even close to that ease of use.
If you use maven and m2e eclipse plugin and a personal forked git repository it works nicely. I do this on my wifes laptop which is Mac and my dev laptop which is Linux all the time. Its one of the reason I hate Ivy and friends is that it just doesn't work as nicely as Maven. The real issue is that there is just not a good Ivy eclipse plugin.
@str you better sync your ".ivy2" directory or your going to have problems. There are just so many problems with your solution I'm shocked you haven't had issues.
Adam, your advice is controversial. Many people, including myself believe best practice is to put IDE metadata under source control, and ensure that it uses portable paths. Hence the poster's question, since sbteclipse doesn't do this right thing here.
The problem Ben is while it maybe convenient lots of things go wrong when doing this. First of all your IDE is not what decides what a valid build is or not. Your build system does. So unless your using Eclipse for releasing I think its dangerous to checkin Eclipse settings especially .classpath. Also if you have any plans on allowing other developers to use different versions of Eclispe as that will likely screw things up let alone different IDE's altogether. But if you have a highly locked down corporate environment then by all means go ahead and check it in :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.