Improve Eclipse WTP support in Gradle 3, HowTo?

buildship
eclipse

(Martin Burchard) #1

I heard in the Buildship Bug Tracker, that the Eclipse WTP support should have been greatly improved with Gradle 3.
Now I wanted to play a little with Gradle 3.0-milestone-2, Eclipse NEON and Buildship 1.0.16.

I created a folder and some files by hand and tried the Buildship importer.
The current result is not, what’s expected but I hope to get support here, to publish the idea for everybody.

The code is available at: https://github.com/MBurchard/BestPractiseGradleWeb

Final solution / Ideas:

  • Multi Project set up (a <- achieved)
  • Project Names should belong together for easier handling in Eclipse (a)
  • all sub project should have the Project Facet Java 1.8 with source folder src/main/java (na <- not achieved)
  • the Web project should have the Dynamic Web Project 3.1 Facet, including Context Root and Content Directory (na)
  • the Web project should be able to be started on a Tomcat from Eclipse without additional set up steps (na)

Because it’s already late here, I finish for today.
Any help is highly appreciated.

Cheers Martin


(Stefan Oehme) #2

Hi Martin,

Buildship 1.0.16 now correctly handles the classpath attributes on WTP projects. This means that e.g. provided or testCompile dependencies are no longer deployed to the server when running in Eclipse.

Buildship 1.0.16 does not yet handle the facets and deployment assembly configuration. You’ll have to run the eclipseWtp task manually after import.

This is a limitation which we want to remove in future Buildship releases.

Cheers,
Stefan


(Stefan Oehme) #3

WTP support is coming, read more here: [Request for feedback] WTP support coming to Buildship


(Martin Burchard) #4

I have uploaded a new version to the GitHub repo named above.
At the moment, I test with Eclipse Neon, BuildShip 1.0.21 and Gradle 3.2.

All above steps are now working out of the box for a web project, that does not need files from another parallel project. :+1:

The new test case covers a Test class, that is written in the API project which is used in the Web project.

After import using BuildShip all projects are in eclipse and look fine. The Web project has correct facets. The only thing I wonder is why the Eclipse facet XML config contains the jst.web 2.4 in addition and why the facets from Gradle are fixed.

<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
	<fixed facet="jst.java"/>
	<fixed facet="jst.web"/>
	<installed facet="jst.web" version="2.4"/>
	<installed facet="jst.java" version="1.8"/>
	<installed facet="jst.web" version="3.1"/>
</faceted-project>

Within Eclipse the Web project has a dependency on the API project and code completion is working fine.
If I now start the Web project on my local Tomcat from inside Eclipse, it starts without any error.
The Controller is available and besides it is not completely correct, it’s working fine.

Then I added the following lines to the StartController

	Test t = new Test();
	t.setName("Hans Wurst");
	System.out.println("Test:" + t.getName());

If the helloWorld method is called, a ClassNotFoundException is thrown because of de.mbur.audit.api.Test class.

The reason? the API project is not deployed to the Tomcat.

Now I changed the API project within Eclipse. I converted it to faceted form, set Java to 1.8 and checked Utility Module.
Eclipse now deployed also the API project to the Tomcat.

So what do I which/expect from BuildShip/Gradle?
It would be great if one can set up facets also if one don’t use eclipse-wtp, because this would enable jst.web also.

<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
  <installed facet="java" version="1.8"/>
  <installed facet="jst.utility" version="1.0"/>
</faceted-project>

Example (the Java facet should automatically set accordingly to sourceCompatibility):

eclipse {
	facet {
		facet name: 'jst.utility', version: '1.0'
	}
}

(Stefan Oehme) #5

You need to apply the eclipse-wtp plugin to utility projects. Then they will be configured correctly.


(Martin Burchard) #6

Yes, looks like… I thought it would also set jst.web, but because of the missing apply plugin: ‘war’ it obviously does not.

apply plugin: 'eclipse-wtp'

eclipse {
	wtp {
		facet {
			facet name: 'jst.utility', version: '1.0'
		}
	}
}

The above build.gradle from the API project works as expected. Thank you for clarification.
Great work with Gradle 3.2 and BuildShip…


(Stefan Oehme) #7

By the way, if there is anything else that you think the eclipse-wtp plugin should do differently, please let us know. We don’t have a lot of WTP experience and are always grateful for more insight.

For instance: Why did you have to add that facet declaration? Looks to me like that should be a default. Can you try without?


(Martin Burchard) #8

Yes Stefan, you are right. For Utility Module one does not need to specify the facet. The following build.gradle is enough:

apply plugin: 'eclipse-wtp'

Which still strikes me:

  • the file .settings/org.eclipse.wst.common.project.facet.core.xml still contains installed facet=“jst.web” version=“2.4” although it was set up as 3.1 by Gradle. It conaints two entries
  • cleanEclipse removes .project and .classpath but leaves the .settings and bin folder
  • The Web project build by BuildShip looks different then the one build with Eclipse. Just for demo I manually changed the API project to Dynamic Web Module using Eclipse, not Gradle

The Web project created by BuildShip lacks of visual representation of:

  • Deployment Descriptor
  • JAX-WS Web Services
  • JavaScript Resources

(Stefan Oehme) #9

Even after running cleanEclipse? The eclipse tasks are currently adding things, but not removing stuff. You currently need to clean explicitly. The reason was to allow users to manually tweak things if necessary. With Buildship 2.0 we’ll clean those files automatically and let the user do adjustments in the build.gradle file instead.

We can’t remove the whole .settings folder because it contains stuff that we did not create. The same is true for the bin folder. Out of the box, cleanEclipse only removes what eclipse generates. You can of course adjust this to your liking.

Since I’m not a WTP user I don’t know what the effect of these is. I assume that we decided to go with a relatively small number of facets and let the user decide which others to add. I’m very open to suggestions what the default behavior for each kind of project should be.


(Martin Burchard) #10

This has nothing to do with cleanEclipse. There are no Eclipse files. It happens during a fresh first import into Eclipse using BuildShip. After this import the facet config file contains two jst.web entries. The one that was specified in the build.gradle (3.1) and the default one (2.4)

Got that. How would I configure this additional behaviour in the build.gradle?

This elements of an Eclipse Web project are no matter of additional facets. As I said. They appear automatically when I use Eclipse to enabled the Dynamic Web Module facet. And it does not matter if I set it to version 2.4, 3.0 or 3.1.
Also if I tried this build.gradle

facet {
	facet name: 'jst.web', version: '3.1'
	facet name: 'wst.jsdt.web', version: '1.0'
}

the facet for JavaScript is enabled in Eclipse, but the Project Layout is incorrect, no JavaScript Resources.

I also don’t know a way to change the project layout in eclipse. As fare as I know, it is done, when activating the facet for Dynamic Web Module.

I did some tests and compared two identical instances of the same project in different folders and the files generated by BuildShip and generated by Eclipse are different at many points…
Left side is BuildShip, right side is from Eclipse
.project


.classpath (I’m not allowed to post more then one image)
img src="/uploads/default/original/2X/6/631c35c24ee0fa40f9640c922ff2266003c80037.jpg" width=“690” height=“24”
.settings\org.eclipse.wst.common.component (I’m not allowed to post more then one image)
img src="/uploads/default/original/2X/b/b62f5682ca019a4119e1ecb21f5f5b446643fdc8.jpg" width=“690” height=“44”
.settings\org.eclipse.wst.common.project.facet.core.xml already mentioned

There are additional files on the Eclipse only side. But they do not seem to matter.
After dozens of Gralde Imports and project deletions from Eclipse and cleanEclipse and Imports of Existing Projects into Workspace, I thing it’s the project facet only, that corrupts it.
The current build.gradle

apply plugin: 'war'
apply plugin: 'eclipse-wtp'

eclipse {
	wtp {
		component {
			contextPath = '/'
			deployName = 'audit'
		}
		facet {
			facet name: 'jst.java', version: '1.8'
			facet name: 'jst.web', version: '3.1'
			facet name: 'wst.jsdt.web', version: '1.0'
		}
	}
}

dependencies {
	compile (project(":${rootProject.name}-API"))
	
	compile "org.springframework:spring-webmvc:$springVersion"
	
	providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
}

What I did then:

  • new clean Gradle import with BuildShip
  • delete project from Eclipse
  • change org.eclipse.wst.common.project.facet.core.xml by deleting the wrong entry installed facet=“jst.web” version=“2.4”/
  • change .project by adding the missing nature org.eclipse.wst.jsdt.core.jsNature
  • reimporting the Project using Existing Projects into Workspace

Now the Project Layout looks nearly correct.

If Gradle or BuildShip, don’t know what is responsible for that, will also be able to do this steps it would be nice, if it in addition also configures the existing src/main/javascript path correctly as source path for JavaScript.


(Stefan Oehme) #11

I think we don’t add the JS nature, because we have no JavaScript support in the war plugin. So there would be no point activating it in Eclipse if it doesn’t work in the build. Of course you can always add this nature in eclipse.project.natures.

The duplicate facet is interesting, I’ll have a look at that. It might be added automatically when the nature is added.

Every Delete task can be configured to delete additional directories.


(Martin Burchard) #12

Isn’t it already the case that BuildShip is adding more to the Gradle project handling? When I run gradle eclipse from command line the result is different then the result of BuildShip.
So if BuildShip detects a configuration for the JavaScript facet why can’t it at the JS nature? It would be a nice enhancement. And in a longer term, the eclipse-wtp task from Gradle should be responsible to create a correct Eclipse environment if it detects the facet configuration for JavaScript.

:+1: Tell me, if you need my support.

Sorry I don’t know how to “overwrite” or enhance cleanEclipse to use this deletion but I’ll look into the documentation… Thank you.


(Stefan Oehme) #13

The result is the same except that we put dependencies in a container to make the .classpath file portable. We don’t do any special handling and don’t intend to add that. The model should be correctly handled in Gradle.

It’s as simple as:

cleanEclipse {
  delete 'bin'
  delete '.settings'
}

(Martin Burchard) #14

One small note: If the Eclipse Project was repaired the described way, a Refresh Gradle Project breaks it again. It re adds the bad 2.4 jst.web facet…


(Donát Csikós) #15

The duplicate facet problem is probably related to this issue. A fix has been implemented and will be available in the Buildship 2.0 release. In the meanwhile, would you mind trying out our latest 2.0 development snapshot and see if works better for you? You’ll find the update sites here.


(Martin Burchard) #16

I Installed the current version from this URL https://builds.gradle.org/repository/download/Tooling_Master_IntegrationTests_Linux_Eclipse46Build/.lastSuccessful/update-site

I also tried this: http://download.eclipse.org/buildship/updates/e46/snapshots/2.x

It kills all the .settings folders again and again. No project is working :frowning:


(Donát Csikós) #17

Delete your projects from the workspace and import them again with the “Existing Gradle Project” wizard.


(Stefan Oehme) #18

Did you maybe change the cleanEclipseWtp task to delete .settings?


(Martin Burchard) #19

@st_oehme I changed the cleanEclipse Task when we talked last time but then recognized that this is a problem.
So no, there are no additional deletions anymore.
For the deletion purpose I created a new Task:

task cleanEclipseCustom {
	delete '.settings'
	delete 'bin'
	delete 'build'
}

@donat I did it this way, but I’ll try again… later…


(Martin Burchard) #20

Is it possible that a task, that is named cleanEclipseCustom is called by Gradle/BuildShip when the Task cleanEclipse ist called?
After removing my custom clean task completely the .settings folder are not deleted any more. In addition I got a Update for BuildShip 2 today, that also may be responsible for the fix.
With BuildShip 2 the wrong jst.web entry is still there and the project is still not correct…

<installed facet="jst.web" version="2.4"/>
<installed facet="jst.java" version="1.8"/>
<installed facet="jst.web" version="3.1"/>