Fix order of source folders in classpath. #364
Conversation
@rgladwell this PR lacks lots of classpath entries, which should be ordered properly. Did you intentionally skip those? |
I find these code reviews go better if we try to politely discuss both the positives and negatives. Depends what you mean by "lacks lots of": after your commit that refactored the classpath API it seems most of the ordering issues were resolved except for the The tests only verify that the |
Ricardo, I meant to be polite. Did you find my tone too hard? I do not, and if it is, that is due to translation, I guess, sorry. I think it would be more safe to explicitly set the order here and do not rely on the other code which may order the entries by luck. Also please note the last change adds the Android entries in a work space configurer, so ordering should be after that. |
No worries, I appreciate English isn't your first language. When you say "set the order" do you mean in the tests? I'm not sure how much detail to set the order: down to the individual order of each classpath container, or just the order of the Is there any reason to believe a |
Now, i would order all the entries in the configurer just like @kingargyle's old implementation did.
I am not really sure, however that was the only way when i created 90b5c7c. When i did it in the |
I think additional code to order the classpath would be redundant after your refactor of the classpath API. It appears only the I can certainly strengthen the tests to prevent regressions though. Does this also mean that the order of the classpath containers themselves is important? Or only that they appear after the source code folders?
I am uncertain myself although the tests seem to be passing. |
I'm with writing tests for now only to verify the order. Good point!
|
The order of the containers is not important for compilation, but it is
better to see a fixed, meaningful order in the gui.
|
I'm not sure how @kingargyle derived the order of the classpath containers. |
f57680e
to
095e429
Compare
Fixed PR, I decided not to test the order of the classpath containers as I'm unsure as to what is the correct order at this time. Also added some minor refactorings. @WonderCsabo please let me know what you think. |
IJavaProject javaproject = JavaCore.create(eclipseProject.getProject()); | ||
IClasspathEntry[] tosort = javaproject.readRawClasspath(); | ||
IClasspathEntry[] sorted = sortClasspath(mavenProject, tosort); | ||
javaproject.setRawClasspath(sorted, new NullProgressMonitor()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure this is the good approach. You could just modify the IClasspathDescriptor
here. Then m2e will persist its contents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. However, I'm trying to experiment with alternatives, but the m2e IClasspathDescriptor
class doesn't allow you to update all its entries, and is basically not easy to order. Instead you have to remove all entries and then add them again in the right order which is also ugly and seems to drop the /gen
folder for some reason.
Unfortunately, the Java sort algorithms also only seem to work on arrays, not sure if there is some other way we could order it.
Any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, the Java sort algorithms also only seem to work on arrays, not sure if there is some other way we could order it.
You can sort any List
w/ Collections.sort()
. Just use it on descriptor.getEntryDescriptors()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point: I did try this and the code is much simpler. However, I think we're going to have to call javaproject.readRawClasspath
because the IClasspathDescriptor
that is passed to this method is stale and lacks a gen/
entry.
When the gen/
is added it breaks the order of the classpath.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that is the problem i faced when i wrote the m2e 1.6 support, which i mentioned to you earlier. :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, at least we've verified it twice. Maybe we should raise with upstream if we haven't already.
I'll revert my changes but tidy the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused: did you mean "m2e should not modify the ClasspathDescriptor" or "m2e-android should not modify the ClasspathDescriptor"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually in some cases Order is necessary for compilation and also for some tooling to beable to look up the source code for a project. Especially if an Eclipse Plugin is only checking for the first source folder when looking up the code, then it is critical that the src/main/java always shows up first. Also, my experience when I was writing the original sorter, is that the particular configurator could run about 3 or 4 times and if you have other maven plugins also configuring and adding their entries, you could get stuff out of order again. Especially if you are adding generated-sources and test-generated-sources to the list of entries. As for how I derrived the order of the claspath containers, it was based on a clean implementation that the old ADT plugin wizards would create a clean project. I then added any Maven stuff to the end of that list. |
@kingargyle do we know if changing the order of the classpath containers would cause problems or is it OK leave this? |
Indeed! That is already handled in this PR.
Good point, i also experienced that. It is more safe to order all the entries, not just the source folders. |
During classpath configuration the order of source code folders changes causing problems with source code lookup, for example during debugging: https://github.com/rgladwell/m2e-android/issues/issue/245 The order should always be: src/main/java src/main/resources src/test/java src/test/resources Android Framework Android Private Libraries Android Dependencies Maven Dependencies Non-runtime Maven Dependencies This change reorders the classpath as above. Includes tests.
PR updated. |
095e429
to
72dbd71
Compare
The only order I think has to occur @rgladwell is that the Android SDK should be the first classpath container after all the sources so that ADT/Andmore finds that in case it is order dependent (haven't really looked). Some of the other is preference, but I'd like to have Maven Runtime, and then Non Maven Runtime in that order but not sure it really matters unless you have different libraries for Tests. |
@rgladwell i am afraid this PR is not correct. The problem is you read the raw classpath, then persist it in your configurer. However, after all raw classpath configurers ran, m2e-core will persist the raw classpath according to the |
@WonderCsabo are you seeing problems on your local workspace? |
This is only a theory. I will try to verify this at home.
|
Seems to be working locally for me. Perhaps a more future-proof iteration of this would be to do the following:
This way we might be able to avoid directly writing the raw classpath and working with m2e. I'll give it a try |
Try to add a new entry as the first entry in the last raw classpath
|
Sorry, I didn't understand that? |
I attempted my suggestion above but it didn't work: lots of test failures. |
Sorry, I quickly wrote down that in email. I will test it shortly after I
arrive home.
|
@rgladwell sorry for my "theory", i think it is not true. This configurer is called when the classpath is resolved, so that is totally cool. I also figured out why the |
:( This worked for my real project, but now target/generated-sources/annotations is added as the first entry. (I am using m2e-apt for that.) |
During classpath configuration the order of source code folders changes
causing problems with source code lookup, for example during debugging:
https://github.com/rgladwell/m2e-android/issues/issue/245
The order should always be:
src/main/java
src/main/resources
src/test/java
src/test/resources
Android Framework
Android Private Libraries
Android Dependencies
Maven Dependencies
Non-runtime Maven Dependencies
This change reorders the classpath as above. Includes tests.