0

So first off, a little background.

I am working on converting an Eclipse Java Web Project to Gradle. We use the Vaadin framework and currently manage the project with Ant/Maven/Ivy. We have another project that contains common code that the web project depends on. In both projects our library files, JARs, are simply included in the source and committed to our VCS. With the switch to Gradle we will be using the preferred method of pulling our dependencies from a repository; mainly Maven Central.

I have completed creating the Gradle build scripts that correspond to our current Ant build scripts. I have one Gradle build script for each project, as well as one at the root for configuration injection along with the settings file. I am using the java and eclipse plugins for both projects and additionally the war and vaadin plugins for the web project.

Now to the problem. When I use Gradle to construct the WAR it works perfectly and the WEB-INF/lib directory contains only the JARs that I would expect, based on the dependency configuration. However, when I use Tomcat inside Eclipse to publish the project I end up with a bunch of additional JARs in the WEB-INF/lib directory. Most of the JARs are harmless and just unnecessary, which is why I have excluded them from the WAR, but there are a couple that are actually problematic because Tomcat already has them. In one case it just ignores the JAR and I get the usual message of:

[Tomcat] validateJarFile(*) - jar not loaded.

In the other case I actually receive exceptions in the console, which is troubling even if the application appears to work correctly. I also noticed that all the dependencies associated with the testCompile configuration are also being published, which really doesn't seem right.

The exact offending JARs are tomcat-jdbc and servlet-api-2.5. The tomcat-jdbc JAR is required for compiling our common code. The servlet-api-2.5 JAR is actually just a transitive dependency of vaadin-client-compiler. I have removed the dependency for the vaadin-client-compiler in our web project, because it doesn't appear to be necessary, but it looks like it is still being pulled in by a configuration in the vaadin plugin for Gradle. However, in both cases I am using the providedCompile configuration of the war plugin to exclude them form the WAR.

So my question is, how do I keep Tomcat/Eclipse from publishing these JARs? How do Gradle and Tomcat/Eclipse communicate, or do they at all? From what I can gather it seems that Gradle and Tomcat/Eclipse only communicate indirectly via the .classpath, that the eclipse plugin for Gradle modifies. Also, I have tried the eclipse-wtp plugin for Gradle. It did not seem to resolve the issue because the problematic JARs were still being copied. I am actually not even sure whether I need to use this plugin or if I can just simply use the eclipse plugin.

I should also add that I did install the Gradle Integration for Eclipse "plugin" via the Eclipse Marketplace. With that I used the Configure -> Convert to Gradle Project option that it adds as well as the Gradle -> Refresh Dependencies functionality that it provides. Other than that, I found it to be a little buggy so I've mostly been running Gradle via the command line.

Below is the output of running gradle -v on my machine:

------------------------------------------------------------
Gradle 1.10
------------------------------------------------------------
Build time:   2013-12-17 09:28:15 UTC
Build number: none
Revision:     36ced393628875ff15575fa03d16c1349ffe8bb6
Groovy:       1.8.6
Ant:          Apache Ant(TM) version 1.9.2 compiled on July 8 2013
Ivy:          2.2.0
JVM:          1.8.0_05 (Oracle Corporation 25.5-b02)
OS:           Mac OS X 10.9.3 x86_64

Please let me know if additional clarification is required. I assume I must be doing something wrong or missing some configuration because surely my scenario is quite common. Many developers use Tomcat inside Eclipse to test web applications locally and with the popularity of Gradle I would be surprised if someone hasn't run into this before. It would seem the main difference with our switch to Gradle, as far as Tomcat/Eclipse are concerned, is that our dependencies are now being loaded from a repository instead of being linked directly in the source.

Any help is greatly appreciated.

asymptoticFault
  • 4,491
  • 2
  • 19
  • 24

1 Answers1

2

However, when I use Tomcat inside Eclipse to publish the project I end up with a bunch of additional JARs in the WEB-INF/lib directory. Most of the JARs are harmless and just unnecessary, which is why I have excluded them from the WAR, but there are a couple that are actually problematic because Tomcat already has them.

This is a known problem with the gradle eclipse tooling. The problem is that it doesn't understand about dependencies with 'provided' scope. See this issue for some details: https://issuetracker.springsource.com/browse/STS-2380

There is a workaround for this problem. Some common dependencies that 'cause problems' can be globally excluded via a list of regexps you specify in the preferences. Open menu "Window >> Preferences >> Gradle >> WTP". That's where you can add regexps that will be used to exclude jars from the 'deployment assembly'.

Kris
  • 3,898
  • 1
  • 23
  • 32
  • Thank you very much for the answer! Coincidentally I actually came across this myself a few hours before seeing your response. Thank you for linking the issue too, it's good to know I'm not the only one having what seems to be a very common and crucial problem. I gave the exclusion list a try and it actually did seem to work; the first time, then it seems to go back to still deploying the problematic JAR. I can't seem to get it to work consistently. Should I be using the **eclipse-wtp** Gradle plugin or just the regular **eclipse** Gradle plugin? Is there a way to refresh the deployment? – asymptoticFault Jun 11 '14 at 13:44
  • The 'eclipse-wtp' project. This the plugin intended to integrate with Eclipse WTP ('Web Tool Platform'). Actually if you using this plugin, it might work best if you disable 'Dependency Management'. This makes gradle tooling go more 'hands off' and just rely on whatever the gradle 'eclipse' task generates. The problem is really the classpath produced via the tooling can't distinguish 'provided' dependencies. It might be the 'eclipse-wtp' plugin handles it correctly. – Kris Jun 11 '14 at 20:06
  • "Is there a way to refresh the deployment?" Not sure if will work but normally the gradle menu 'refresh all' should refresh all the project settings, just as if you did a 'fresh' import. – Kris Jun 11 '14 at 20:11
  • Sorry for the delay. I still cannot seem to consistently exclude the JAR in question from the deployment. From what I understand this exclusion list should do the trick. Is it possible the embedded Tomcat instance is not considering that list when I tell it to publish the project? – asymptoticFault Jun 17 '14 at 13:21
  • The list is supposed to affect the 'component.xml' file. This is an eclipse thing. I beleave the 'filter' should be applied to the component assembly (component.xml file in project) upon 'Gradle >> refresh all'. If it doesn't then I'd consider that bug and you should probably raise bug report in the STS issue tracker (https://issuetracker.springsource.com/browse/STS) – Kris Jun 18 '14 at 22:39
  • By the 'component.xml' file do you mean the _org.eclipse.wst.common.component_ file? I have seen that this file does seem to control what is deployed and the **eclipse-wtp** plugin does modify it. Do you know of any documentation on this file? It would be useful to know exactly how it is interpreted. With the impending release of Eclipse Luna I am going to give this another try with that and Tomcat 8 to see if the problem gets resolved. I appreciate all your help **Kris** and will upvote the answer but I am not sure I can accept it just yet. – asymptoticFault Jun 23 '14 at 14:12
  • Yes, that's the file I meant. There is no documentation that I know of. I think this file is in a format considered 'internal' to Eclipse WTP tooling. Thinking about my answer above... maybe actually could be refined. It may depend on whether you use Gradle tooling with 'Dependency management' enabled or not. Are you? The 'workaround' I recommended was implemented for the 'Dependency managment enabled' case. The other case may not need the fix. The problem appeats in the 'Gradle classpath container' dependecny which is only used with 'Dependency Management = enabled'. – Kris Jun 23 '14 at 16:25