Spring Boot incorrectly loads test configuration when running from eclipse+gradle - eclipse

When I run Spring Boot application from Eclipse (STS) as 'Java Application' or as 'Spring Boot App' the app fails because it tries to load configurations (#Configuration) from test classpath.
The thing is that it works for maven based builds correctly, but not for gradle.
The only workaround I see is to rename test package to something else to hide it from classpath scanning.
Overall the question is - how to make it work properly? I'd assume that SpringToolSuite team encounters this problem on a daily basis or I do something incorrectly.
Here's a test project which works when imported as maven, but fails when imported as gradle: https://github.com/mabn/spring-boot-integration-test
Here's a year-old STS issue - is it still relevant?
Here's another one marked as resolved
Similar question about maven projects
I'm using STS 3.7.1

The thing is that it works for maven based builds correctly, but not for gradle.
Yes, unfortunately that is the case. Gradle doesn't deal properly with configuring eclipse's runtime classpath at all. This is even the case with Gradle's own new BuildShip eclipse plugin.
See this issue I recently raised:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=482315
The resolved bug you found is indeed resolved, but it only concerned the maven/m2e case, which is in fact fixable (m2e does this correcty for "Run As >> Java Project" and we adopted a similar fix for "Run As >> Spring Boot App"). However, that fix is maven-specific as the gradle case is not really fixable until this Gradle tooling-api issue ticket is resolved:
https://issues.gradle.org/browse/GRADLE-1777

I had to introduce separation with profiles for this.
Having all test marking with
#ActiveProfiles("srv-test") and main configuration with #Profile({"local", "docker"})

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.

Eclipse/Tomcat publishing unnecessary/problematic dependencies

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

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.

Eclipse configuration to support dual Equinox/Felix environments

What are some configuration changes to make Eclipse PDE best support working with both Equinox and Felix?
Here's an example problem I'm currently having. I can run my application ok via the Eclipse OSGi Framework launcher. Similarly, there are no compilation problems in PDE. However, when running in Felix I will get NoClassDefFoundErrors:
java.lang.NoClassDefFoundError: org/w3c/dom/DOMException
My understanding is it's my Eclipse setup that is at fault here; org.w3c.dom is not a 'default' OSGi package and shouldn't be loaded when I run it in Eclipse. Similarly, the import in my code for org.w3c.dom.DOMException should be an error.
I know how to fix this for Felix: declare an Import-Package. But that's not my question. My question is how to force Eclipse PDE to take on a closer configuration to Felix... basically to make it stricter in loading packages?
I think Equinox does behave like Felix, if you run it stand alone. It's more of an Eclipse legacy thing than an Equinox thing, as stated on osgi.org.
As far as I know, there isn't any way to override the boot delegation from Eclipse, but I'd love to be proven wrong, as I've faced this problem often.
If you are developing a server application I recommend to not use the PDE at all. I am using maven and the maven bundle plugin to develop my bundles. Then I deploy on Apache karaf. Debugging also is quite simple by using the karaf dev:watch command and remote debugging. I never really missed the PDE features and they never worked well with my maven build.
This sounds like that launcher is setting bootdelegation to legacy mode. See the following page on the OSGi Wiki: http://wiki.osgi.org/wiki/Why_does_Eclipse_find_javax.swing_but_not_Felix%3F

Can't get compile on save / hot deploy feature to work with maven based webapp in eclipse or netbeans

So our new webapp project is based on maven. I'm really liking the dependency management and IDE agnostic approach but I'm having problems with compilation and debugging.
Here's how I would currently get a clean copy of the project working
Check out the main project from SVN
Open the project in IDE (I've tried in eclipse 3.4 and netbeans 6.7)
The IDE will automatically open two subprojects one being the webapp, the other being a supporting utils jar.
From the command line I run mvn war:inplace on the webapp module which builds a working copy of the webapp with all dependencies in WEB-INF/lib/
This then runs fine but whenever I change a java class I have to clean and build / reload the app context.
I've googled high and low but no one seems to be complaining about this so I guess there must be something really obvious I'm missing. How is everyone else handling incremental compilation and hot deploy with maven?
To clarify all I'm looking for is the replicate the behavior I used to have before maven where I could make simple changes to java classes and they would be instantaneously compiled and hot deployed to a running webapp. I don't need anything fancy like jRebel etc I just want the new tool to give me the same functionality I enjoyed with my old tools.
If you can use mvn jetty:run it will read the classes and resources directly from the project. Using Maven2 Eclipse plugin and running the server embedded in Eclipse has auto-publishing, which gets you there in the end, although it's slower. And JRebel starting with 2.0 (as you may know) can map the Maven module directly to the deployed application, so you get instant build and redeploy. Those are the only solutions I know of.
Netbeans should support it out of the box. Though, there remains a bug related to this: http://netbeans.org/bugzilla/show_bug.cgi?id=177230
In-place deployment works for me with Netbeans 7.0.1 and Tomcat 6.0.x if I use Tomcat 7.0.x in-place deployment doesn't work. Tomcat always copies application to $CATALINA_HOME/temp :(