Eclipse/Tomcat publishing unnecessary/problematic dependencies - eclipse

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.

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'.

Related

Understanding STS: Spring boot application works fine from STS but when gradle is used to build jar, the build fails

My spring boot application works fine when run from Spring Tool Suite. However at the time of project deployment when I use Gradle command to build jar file, I get compile error - with error message saying a specific package is missing.
The root cause was that I had missed to add a specific dependency to build.gradle. After adding the missing dependency the build was successful.
Can someone explain how STS was able to refer to the "missing" dependency and able to run the application successfully in development environment?
Is it that STS and Gradle has two different locations where dependencies are stored?
When using STS (or any other IDE for that matter) and you are manually (or through a wizard) adding jars to the classpath entries those will only be available in your IDE.
What you should be doing is adding additional dependencies to your pom.xml or build.gradle (depending on your tooling), which then in turn should be picked up by your IDE again.
NOTE: Some IDEs will automatically detect additions to the classpath and add them to your build files as well. Not sure if STS (and thus Eclipse) does this.

Maven Eclipse Integration

I have recently started out on Maven. I am trying to integrate Maven+eclipse(Juno)+tomcat7.
I have downloaded m2e-wtp plugin for eclipse and created a Maven project whose structure follows a standard Maven project structure. It is also configured a dynamic web project.
It is a multi module project with two modules of flex(f1 AND f2) and one module of webapp(w).I have configured all the plugins correctly and there is no problem with configuration of POMs.
What I want to achieve is :
When I clean and Build project in Eclipse using Project-->Clean,Eclipse does not build the war in target folder of my web application project (w). I also does not copy any of the flex resources to target folder. However,
When I run the project as maven build by right-clicking the web application project and running it as a "maven install" it creates everything as expected.
My question is that if it is possible to achieve what I mentioned in point (1)? Or the only correct way to do this is the way mentioned in point (2).
I am also not able to deploy the generted files in step 2 automatically in tomcat.
Do I need to use another maven plugin for this?
Please note that this i my first experience with Maven + eclispe. I have followed certain tutorials. So, Please be lenient while voting negatively.
From what I know it is not possible to force Eclipse to use Maven directly (I would gladly be proven wrong).
Eclipse does not use Maven to build (1). Using the m2e plugin, it is possible to run maven to perform the build as you discovered (2).
If you are looking for that kind of tight integration you can look at NetBeans or IntelliJ who are using Maven natively.
EDIT:
About (3) there is a Tomcat-Maven-Plugin that can deploy the WAR file created on a running tomcat instance. Check the Usage page for more details.

JUnit test fails with java.lang.ClassNotFoundException: com.mysql.jdbc.Driver on Tycho environment

I have a very strange situation. I have a set of eclipse plugin projects which I am using tycho and maven for building them. I used JDBC driver in one of the projects and I have a test plugin to test this project. Since the com.mysql.jdbc plugin was not available in the eclipse p2 repository ( and we don't have our own p2), I imported the jdbc plugin and created an OSGi plugin and add the dependency to my local plugin.
I have multiple eclipse workspaces sat up. Only in the very first workspace that created the test and jdbc plugin, junit tests are working when I run them using eclipse run as -> Junit test command. When others or even me checkout the source codes and try to run the test in different workspaces, this exception is thrown:
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
I also tried using tycho integration test (runing mvn integration-test) but that doesn't work neither and I still get the same exception. I tried searching for this a lot but I couldn't find the answer.
UPDATE:I think it is not a tycho problem. I just tried to create the eclipse plug in based on com.jdbc.mysql jar. The workspace I created this on is working fine. But as soon as I commit the code and import the project in another workspace the tests stop working. All of the settings are same among two workspaces, one is working the other gets the ClassNotFound exception!
Tycho computes the OSGi runtime based on the transitive dependencies of your test bundle.
You probably have no design-time dependency on the mysql driver bundle (but rather only on the JDBC interfaces it implements)
Try adding a test runtime dependency on the mysql jdbc driver bundle.
See http://wiki.eclipse.org/Tycho/FAQ#How_to_add_a_undeclared_dependency.3F__.28e.g..2C_OSGi_declarative_service.29 on how to do this.
ClassNotFoundExceptions in an OSGi runtime indicate that there is something wrong in the imports and/or export declarations in the OSGi manifests. The most frequent case is that a bundle claims to export a certain package, but doesn't actually have the binaries/class files of that package.
In a Tycho build, this can easily happen if you don't have the entry . in the bin.includes property in the build.properties.

JUnit uses wrong Base64

I wanna use the class Base64 from commons-codec 1.5 and when I run the code on Server this works fine. My application runs on Websphere 7.0.
But when I run my JUnit tests the wrong Base64 Class is choosen, when i ask the Class with:
System.out.println(Base64.class.getProtectionDomain().getCodeSource().getLocation());
the output is: file:/C:/EProg/IBM/SDP80/runtimes/base_v7/plugins/com.ibm.ws.prereq.soap.jar
Thats definitly the wrong Version.
And an error occurs because of the wrong Version:
java.lang.NoSuchMethodError:
org/apache/commons/codec/binary/Base64.decodeBase64(Ljava/lang/String;)
The crazy thing is, that happens only it i choose one Test and run it with Run As: JUnit Test in Eclipse, if I run the whole thing with Maven everthing works fine.
I use JUnit 4.8.1 and Eclipse Indigo Service Release 2 with some Plugins for Websphere, GWT and Maven.``
com.ibm.ws.prereq.soap.jar is an OSGi bundle, and in WebSphere (which is built on an OSGi container), the classes in org.apache.commons.codec.binary are not visible to applications because that package is not exported by the OSGi bundle (you can examine the list of exported packages by looking at the META-INF/MANIFEST.MF file in com.ibm.ws.prereq.soap.jar). That explains why you don't encounter any issue when running your application in WebSphere.
On the other hand, when you add that JAR to a Java project in Eclipse, it will be treated like a simple JAR, not an OSGi bundle, and all packages will be visible. In your case this creates a conflict with another commons-codec dependency.
I guess that the reason why you don't encounter that issue in Maven is that com.ibm.ws.prereq.soap.jar is only a dependency of your Eclipse project, but not of your Maven project.
Unfortunately there are not many (simple) ways to solve that issue. One is to remove com.ibm.ws.prereq.soap.jar from your Java project (I doubt that you are actually using Apache SOAP). The other is to change the order, so that your other commons-codec dependency comes before com.ibm.ws.prereq.soap.jar.
It looks like a class path issue. More precisely, Eclipse integration with Maven. I would investigate Eclipse dependencies and make sure that it uses Maven for dependency management.
You can do it in two ways, either you can run mvn eclipse:eclipse command or use M2Eclipse plugin. If you use the later, then there is a update dependency option, in the project context menu.

Maven Eclipse Runtime Plugin Dependency

We have a multi-module maven project that was recently converted from Ant+Ivy. One of the modules is a legacy custom pluggable component which looks for plugins on the classpath and loads them. Another module in the multi-module project is a plugin implementation that is run by the aforementioned plugin.
When running our custom application server from an eclipse run configuration, we must include each of our plugins on the classpath. As we build within the eclipse workspace these plugins are not compiled to a jar. Hence, there is no jar artifact to include.
If I add the plugin module project as a dependency in the eclipse run configuration, its transitive dependencies (supplied by Maven) are not inherited. Hence, class not found exceptions occur when the plugin is found and loaded by the Application Server.
The problem here is that upon importing the multi-module project, the m2e plugin does not set the maven container to be exported. Thus the missing transitive dependencies.
Is there any way to make this work whilst still running in eclipse using "build in workspace" for both the Application Server component and its plugins.
Ivy is just a dependency management tool where as Apache Maven is a software project management.
Means It can handle all process in software development like compiling,building it to jars, search for depencies,linking, etc.
you no need to give your jars in classpath instead put it in your local repository or edit the pom.xml to fetch from remote repository.
this link http://ant.apache.org/ivy/history/2.0.0/use/makepom.html