Skip to content
This repository has been archived by the owner on Nov 10, 2017. It is now read-only.

Fix order of source folders in classpath. #364

Merged
merged 1 commit into from Jul 14, 2015
Merged

Conversation

rgladwell
Copy link
Owner

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.

@WonderCsabo
Copy link
Contributor

@rgladwell this PR lacks lots of classpath entries, which should be ordered properly. Did you intentionally skip those?

@rgladwell
Copy link
Owner Author

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 /gensource folder, and the business code changes are mostly for this.

The tests only verify that the src/main, 'gen', 'src/test' and classpath containers (as a group) are in the correct order. It doesn't verify the resources folders. This is sufficient to test the change I've made, but perhaps not sufficient to prevent classpath order regressions in the future. I can add more conditions if you think this would be necessary.

@WonderCsabo
Copy link
Contributor

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.

@rgladwell
Copy link
Owner Author

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 src/* folders including src/main/java?

Is there any reason to believe a WorkspaceConfigurer is called after a RawClasspathConfigurer?

@WonderCsabo
Copy link
Contributor

When you say "set the order" do you mean in the tests?

Now, i would order all the entries in the configurer just like @kingargyle's old implementation did.

Is there any reason to believe a WorkspaceConfigurer is called after a RawClasspathConfigurer?

I am not really sure, however that was the only way when i created 90b5c7c. When i did it in the 90b5c7c, the Android containers were not available, yet.

@rgladwell
Copy link
Owner Author

Now, i would order all the entries in the configurer just like @kingargyle's old implementation did.

I think additional code to order the classpath would be redundant after your refactor of the classpath API. It appears only the /gen folder is unordered.

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 not really sure, however that was the only way when i created 90b5c7c.

I am uncertain myself although the tests seem to be passing.

@WonderCsabo
Copy link
Contributor

WonderCsabo commented Jul 13, 2015 via email

@WonderCsabo
Copy link
Contributor

WonderCsabo commented Jul 13, 2015 via email

@rgladwell
Copy link
Owner Author

better to see a fixed, meaningful order in the gui.

I'm not sure how @kingargyle derived the order of the classpath containers.

@rgladwell rgladwell force-pushed the reorder-classpath branch 2 times, most recently from f57680e to 095e429 Compare July 14, 2015 09:58
@rgladwell
Copy link
Owner Author

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());
Copy link
Contributor

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.

Copy link
Owner Author

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?

Copy link
Contributor

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().

Copy link
Owner Author

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.

Copy link
Contributor

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. :(

Copy link
Owner Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner Author

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"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kingargyle
Copy link
Contributor

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.

@rgladwell
Copy link
Owner Author

@kingargyle do we know if changing the order of the classpath containers would cause problems or is it OK leave this?

@WonderCsabo
Copy link
Contributor

@kingargyle

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.

Indeed! That is already handled in this PR.

Especially if you are adding generated-sources and test-generated-sources to the list of entries.

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.
@rgladwell
Copy link
Owner Author

PR updated.

@kingargyle
Copy link
Contributor

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.

@WonderCsabo
Copy link
Contributor

@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 ClasspathDescriptor. I think it will overwrite your changes. :(

@rgladwell
Copy link
Owner Author

@WonderCsabo are you seeing problems on your local workspace?

@WonderCsabo
Copy link
Contributor

WonderCsabo commented Jul 15, 2015 via email

@rgladwell
Copy link
Owner Author

Seems to be working locally for me.

Perhaps a more future-proof iteration of this would be to do the following:

  1. Change the AddGenFolderClasspathConfigurer to be a RawClasspathConfigurer so it runs before the ReorderClasspathConfigurer.
  2. Update ReorderClasspathConfigurer to directly order the IClasspathDescriptor as you suggest above.

This way we might be able to avoid directly writing the raw classpath and working with m2e.

I'll give it a try

@WonderCsabo
Copy link
Contributor

Try to add a new entry as the first entry in the last raw classpath
configurer to the descriptor.
On Jul 15, 2015 16:23, "Ricardo Gladwell" notifications@github.com wrote:

Seems to be working locally for me.

Perhaps a more future-proof iteration of this would be to do the following:

  1. Change the AddGenFolderClasspathConfigurer to be a
    RawClasspathConfigurer so it runs before the ReorderClasspathConfigurer
    .
  2. Update ReorderClasspathConfigurer to directly order the
    IClasspathDescriptor as you suggest above.

This way we might be able to avoid directly writing the raw classpath and
working with m2e.

I'll give it a try


Reply to this email directly or view it on GitHub
#364 (comment)
.

@rgladwell
Copy link
Owner Author

Sorry, I didn't understand that?

@rgladwell
Copy link
Owner Author

I attempted my suggestion above but it didn't work: lots of test failures.

@WonderCsabo
Copy link
Contributor

WonderCsabo commented Jul 15, 2015 via email

@WonderCsabo
Copy link
Contributor

@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 IClasspathDescriptor cannot be used: IJavaProjectConfigurator.configureClasspath is used to configure the Maven classpath actually, so the descriptor only contains the Maven classpath entries.

@WonderCsabo
Copy link
Contributor

:( 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.)

@rgladwell rgladwell deleted the reorder-classpath branch July 19, 2015 11:51
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
3 participants