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>
str
  • 42,689
  • 17
  • 109
  • 127
  • well, you should not use absolute file paths. Put all of your dependencies into a Simple Project, then add workspace references. – DomV Feb 02 '13 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. – str Feb 02 '13 at 15:44
  • That's what [SCM](http://en.wikipedia.org/wiki/Software_configuration_management) are used for... – ndeverge Feb 04 '13 at 15:17
  • ...and build tools like maven (or even a properly configured ant, but that is harder to do correctly). – Hauke Ingmar Schmidt Feb 04 '13 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. – str Feb 04 '13 at 16:08
  • @his We use sbt as a build tool. But how should this help? – str Feb 04 '13 at 16:09
  • I don't know sbt but it should be possible to create or update the local project configuration including `.classpath` completely from the build tool's project description - if there is an Eclipse integration. Regarding the SCM: Branch and merge, that is the whole use. It is not a remote backup. – Hauke Ingmar Schmidt Feb 04 '13 at 16:18
  • @his +1 for branch and merge – ndeverge Feb 04 '13 at 16:32
  • @his I sometimes have to change the computer for 5 minutes and instantly for meetings etc. Branching and merging is overkill for that. – str Feb 04 '13 at 16:34
  • You just check in / check out _your_ branch, you don't branch and merge everytime. That is not more work than a Dropbox sync which doesn't semantically understand what it does. Plus it solves your original problem completely. – Hauke Ingmar Schmidt Feb 04 '13 at 16:36
  • And for meetings or demonstrations in-house there is a much more appropriate tool: Remote desktop (Windows built in, VNC, Teamviewer, remote X session...). – Hauke Ingmar Schmidt Feb 04 '13 at 18:12
  • @his I certainly don't dispute the advantages of a real SCM over Dropbox in general, but it almost certainly has ***nothing*** to do with the problem OP is having! .classpath is a file that Eclipse uses that is best checked in, and it's got absolute paths because it's a generated file that's being generated wrong. SVN or Git isn't going to resolve problems with the contents of a file. – sharakan Feb 05 '13 at 01:28
  • There should be no need to check in _any_ IDE specific files. A build tool with IDE support should be able to create those instantly. It has nothing to do with the OPs problem insofar as it is a WTF setup that needs but can't be fixed - but which can be easily avoided by doing it right from the beginning. Contrary to the OPs statement this IS about SCM and the lack of knowledge about how to use it, especially in conjunction with a build tool. – Hauke Ingmar Schmidt Feb 05 '13 at 06:22
  • @his Reasonable people disagree on checking in IDE specific files. Personally I like people to be able to install Eclipse from scratch, check out our projects, and get going. Other people agree (http://stackoverflow.com/questions/3611728/java-project-should-classpath-project-file-be-committed-into-repository, http://stackoverflow.com/questions/2818239/classpath-and-project-check-into-version-control-or-not, etc). OP is 'checking it in'. Fine with me. You don't want to check yours in? That's fine with me too. – sharakan Feb 05 '13 at 14:18
  • @his as to SCM vs Dropbox. Assuming you'll accept for the moment that some people check in .classpath and that it's not a silly thing to do (stop here if you won't accept that), then I hope you'll agree that checking OP's .classpath in to SVN, then checking it out on another machine, would give him exactly the same problem (absolute paths in the file content) as putting it in to Dropbox and getting it out. – sharakan Feb 05 '13 at 14:23
  • @sharakan Actually, the .classpath file is not version controlled. I'm sorry if that was not clear. – str Feb 05 '13 at 14:39
  • @str I didn't mean that it was, as you didn't say, just that it's reasonable to share it between two machines using whatever mechanism you're sharing the files with. And further, that the mechanism that you're using to share the file is irrelevant to it's contents. – sharakan Feb 05 '13 at 14:43
  • @nico_ekito The laptop I use has not enough power and there is no budget for a new one. – str Feb 08 '13 at 09:18

5 Answers5

1

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.

sharakan
  • 6,821
  • 1
  • 34
  • 61
  • Looked promising but apparently that setting does not influence the .classpath file in any way. – str Feb 04 '13 at 17:08
  • @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? – sharakan Feb 04 '13 at 17:37
  • I tried that already but it has no influence on the paths either. Thanks for trying to help. – str Feb 04 '13 at 19:08
  • @str looks to me like a bug in sbt eclipse then... good luck. – sharakan Feb 04 '13 at 19:23
  • @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... – sharakan Feb 05 '13 at 01:31
  • No I did not. As you can see in my own answer, I solved it with a simple symbolic link. However, I will look into your suggestion when I got some free time. Thank you. – str Feb 05 '13 at 10:36
  • I awarded the Bounty to you as you seemed to be the only one who tried to solve my problem with the given requirements in mind. – str Feb 08 '13 at 09:21
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.

str
  • 42,689
  • 17
  • 109
  • 127
  • 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... – mmey Feb 07 '13 at 14:58
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.

Mr.Me
  • 9,192
  • 5
  • 39
  • 51
  • 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 ;) – str Feb 02 '13 at 15:12
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?

E-Riz
  • 31,431
  • 9
  • 97
  • 134
  • 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. – str Feb 04 '13 at 16:05
  • 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. – E-Riz Feb 04 '13 at 21:38
  • 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. – E-Riz Feb 04 '13 at 21:40
-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) ?

Adam Gent
  • 47,843
  • 23
  • 153
  • 203
  • 1
    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. – str Feb 06 '13 at 09:06
  • 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. – Adam Gent Feb 06 '13 at 15:27
  • @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 Gent Feb 06 '13 at 15:34
  • 1
    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. – Ben Hutchison Jun 08 '13 at 10:47
  • 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 :) – Adam Gent Jun 08 '13 at 14:35