ervandew / eclim

Expose eclipse features inside of vim.
http://eclim.org
GNU General Public License v3.0
1.04k stars 127 forks source link

Bug report: Classpath ordering #350

Closed dhleong closed 10 years ago

dhleong commented 10 years ago

Eclipse has a "Run" command that seems to do the right thing wherever I am—if I'm on a class file, it runs the project. If I'm in a JUnit test, it executes the test. I realize that eclim has its :Java command, but that doesn't help Android builds.

~~I set up a workaround using BetterTouchTool where, if I hit the F15 key while in Vim, it sends the same shortcut to Eclipse (which I have bound to the Run key). ~~

Since would likely not make much sense in a headless environment it is understandable that it hasn't been developed, but if you have any ideas how I might go about doing this on my own (even if just some maps in my .vimrc), I'd greatly appreciate it. Otherwise, I'd love to be able to map—say, <leader>er—to have eclipse run the current file I'm viewing "as it should be run." I would even be happy with a simple :ProjectRun that doesn't care about JUnit tests at this point, but some sort of dispatch-style JUnit runner in a split would be magical (I know, I know, I'm dreaming, but if anyone even has an idea about this one, and I can find time, I might try to do it myself.)

Thanks!

EDIT: see below

dhleong commented 10 years ago

Oh! I just saw the :JUnit command. Not sure how I missed it, but it doesn't seem to use the same classpath as eclipse (or something). In particular, robolectric-based tests for Android projects that work in eclipse fail with eclim, throwing the "Stub!" error.

dhleong commented 10 years ago

Okay, https://github.com/ervandew/eclim/pull/177 exists (though is woefully old and neglected), I'm going to change the scope of this to the JUnit + robolectric issue.

I looked into this issue briefly and I believe the problem is in org.eclim.plugin.jdt.util.ClasspathUtils. At least for the JUnit tests, it has a huge amount of redundant copies of jars. For example,

// JUnitCommand.java:235
    getContext().out.println(Arrays.asList(paths));

Produced:

[/Users/dhleong/Documents/workspace/ApeMinusTest/bin, /Users/dhleong/git/ape/bin/classes, /lib/android-sdk/platforms/android-17/android.jar, /Users/dhleong/git/ape/libs/android-support-v4.jar, /Users/dhleong/git/ape/libs/ape-gson-2.2.4.jar, /Users/dhleong/git/ape/libs/ape-gson-2.2.4.jar, /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/classes.jar, /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/ui.jar, /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/jsse.jar, /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/jce.jar, /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/charsets.jar, /System/Library/Java/Extensions/AppleScriptEngine.jar, /System/Library/Java/Extensions/dns_sd.jar, /System/Library/Java/Extensions/j3daudio.jar, /System/Library/Java/Extensions/j3dcore.jar, /System/Library/Java/Extensions/j3dutils.jar, /System/Library/Java/Extensions/jai_codec.jar, /System/Library/Java/Extensions/jai_core.jar, /System/Library/Java/Extensions/mlibwrapper_jai.jar, /System/Library/Java/Extensions/MRJToolkit.jar, /System/Library/Java/Extensions/QTJava.zip, /System/Library/Java/Extensions/vecmath.jar, /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ext/apple_provider.jar, /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ext/dnsns.jar, /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ext/localedata.jar, /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ext/sunjce_provider.jar, /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ext/sunpkcs11.jar, /Users/dhleong/git/ape-minus/bin/classes, /Applications/eclipse/plugins/org.junit_4.11.0.v201303080030/junit.jar, /Applications/eclipse/plugins/org.hamcrest.core_1.3.0.v201303031735.jar, /lib/android-sdk/platforms/android-18/android.jar, /Users/dhleong/git/ape-minus/libs/okhttp-1.5.4.jar, /Users/dhleong/git/ape-minus/libs/httpmime-4.2.1.jar, /Users/dhleong/git/ape/libs/android-support-v4.jar, /Users/dhleong/git/ape/libs/ape-gson-2.2.4.jar, /Users/dhleong/git/ape/bin/ape.jar, /Users/dhleong/git/ape-minus/libs/httpmime-4.2.1.jar, /Ape/libs/ape-gson-2.2.4.jar, /Users/dhleong/git/ape-minus/libs/okhttp-1.5.4.jar, /Users/dhleong/code/robolectric-2.2-jar-with-dependencies.jar, /lib/android-sdk/platforms/android-16/android.jar, /Users/dhleong/code/google-gson-2.2.4/gson-2.2.4.jar, /Users/dhleong/code/junit-benchmarks-0.7.0/junit-benchmarks-0.7.0.jar]

This is for a test project ApeMinusTest that depends on ape-minus which in turn depends on ape. You'll notice that almost all dependencies are duplicated several times, but the robolectric dependency—the one that is very important and MUST be before any of android.jar is quite far down the list.

I can look further into the ClasspathUtils but if someone else is more familiar with the codebase and has some ideas that'd be great.

dhleong commented 10 years ago

Okay! I managed to get my tests to run in eclim by messing with the CP setup in Eclipse, and this PR: https://github.com/ervandew/eclim/pull/353

For whatever reason, the ape-minus project was exporting the JUnit4 dependency, which is how ApeMinusTest was able to compile despite not having the dependency itself. I fixed that, then re-ordered the JUnit4 to be above robolectric and android, and everything worked.

So, the PR makes it possible, but the CP is obviously still not exactly how Eclipse orders it, else it would've worked without any changing. Perhaps Eclipse does some weird ordering based on the IClasspathEntry type?

I'll leave this ticket open for now in the hopes that @ervandew will have some ideas about how Eclipse builds its classpaths to improve this further....

ervandew commented 10 years ago

I'm going to close this out since the :JUnit command, and others that use eclim's classpath building/ordering, where never intended as direct replacements to any eclipse junit command, etc. My intention was never really to have eclipse in vim, it was to have ide features in vim, so I did not always use eclipse features directly when I felt that it would be easier to build and maintain something that didn't have to jump through as many eclipse hoops (like using the ant api for running junit tests).