Spring RestTemplate dependency issue in Ear - spring

The organisation I work for has a few standalone services using Spring Boot and RestTemplate to communicate with each other and the main monolith (classical skinny War in Ear).
However, we are running into problems with the classpath when we try to get RestTemplate running inside the Ear, but not inside the War. We don't consider making a rest call to be part of the web application, so we moved that code up to a library which gets packaged in EAR/lib. This moved spring-web (4.1.6.RELEASE) to EAR/lib as well, at which point WebApplicationInitializer code stops working.
Is there are way to get the application still kickstarted with spring-web inside EAR/lib rather than WEB-INF/lib? Or should we resign ourselves to either using RestTemplate exclusively in the War/finding an alternative to RestTemplate?

Never mind, apparently when spring-web isn't deployed in WEB-INF/lib, WebApplicationInitializers don't work. We can work around that.

Related

Spring Boot JarFileSystem for wrapped JARs

I've got a Spring Boot application packaged as an Uber JAR. One of the wrapped JARs has logic within it to utilize a Java FileSystem for walking a resource tree that is embedded in that particular JAR file.
Unfortunately, this statement appears to be true:
Now opening jar files isn't a big deal. Esp with the introduction of the JarFileSystem. However Spring Boot includes jar files inside their jars. There is currently no support for that. You can't create a JarFileSystem inside a JarFileSystem.
With that being said, Spring Boot has a fair amount of handling surrounding it's wrapped JARs:
JarURLConnection
Everything else under org/springframework/boot/loader/jar
However, there doesn't appear to be any mechanism for registering Spring Boot's approach as a FileSystemProvider...
org.springframework.boot.loader.LaunchedURLClassLoader unable to load 3rd party FileSystemProvider implementation from spring boot executable JAR seemed like a similar problem, but didn't appear to be directly related.
Has anyone had any luck creating a FileSystem for one of Spring Boot's wrapped JARs?

spring-boot-starter-web with web application type NONE. Why?

I had never used CommandLineRunner before, because I've always written web servers. This time I'm building a microservice (CRON job) that wakes up, make some rest and db calls, and stops.
For this project, like others, initially I had the following dependency:
implementation "org.springframework.boot:spring-boot-starter-web:$springBootVersion"
Until I found out there is something called CommandLineRunner and, as I don't need a web server running, I can actually turn it off by .setWebApplicationType(WebApplicationType.NONE);
Now I'm wondering what's the point of including spring-boot-starter-web if we turn off its web server? I'm using Spring Boot framework to use its dependencies by default (things like jackson, etc.) and for its dependency management framework.
(Side note: I tried to move to sprint-boot-starter but there the following issue that I couldn't resolve, so I think I keep using spring-boot-starter-web :
Correct the classpath of your application so that it contains a single, compatible version of org.springframework.http.converter.json.Jackson2ObjectMapperBuilder)
We can see that spring-boot-starter-web includes:
spring-boot-starter
spring-boot-starter-json
spring-boot-starter-tomcat
spring-web
spring-webmvc
hibernate-validator
Looking at where Jackson2ObjectMapperBuilder is located we can see that it is in spring-web which is included by spring-boot-starter-json.
I suspect if you add spring-boot-starter-json you will be one step closer to running your service without the web server component.
Maven dependency analyzers can save quite a bit of trouble in the future by starting at the top and looking at what each of the POM files include.

Can Jersey resources classes be instantiated in Spring Boot if they're external?

I'm developing a Spring Boot app using Jersey for Rest.
The app will regularly have Rest controller and supporting classes added to it, basically adding small, specific logic at specific endpoints.
I'd like to be able to drop jars containing Jersey controllers into a directory specified by loader.path and have them created (including Spring auto-wiring) by just restarting the server.
Some Jersey resources form the base of the application and these are working fine because I've registered them via a ResourceConfig class but I'd really like to add resources without requiring a rebuild of the app.
Is this possible? I'm failing to get the resources created, I'm not even sure they're in the classpath.
In application.properites, I added:
-Dloader.path=lib/,resources/
and I've copied the jars into these folders, but they don't get instantiated.
Anybody got any ideas?

Deploying a third party war in a Spring Boot embedded container

Pardon if this feels a bit of "necroposting". I looked and found only one similar question with no answers here (Spring-Boot Embedded Wars).
I have a service packaged into a spring boot (1.0) container. This service uses activiti (www.activiti.org) to manage some buisiness processes. I am trying to deploy inside the same spring boot container, the war for activiti-explorer. This war has its own web.inf, spring config, et cetera, so it may conflict with the existing spring config, but nonetheless, I'd like to try to deploy that war as it is.
I haven't found any way to do that, and suspect that spring boot doesn't support the deployment of pre-package wars into the embedded container, isn't it?
Just as a warning, I think I can't put the extracted war into the spring-boot jar as I feel it needs a fully functional web container. If spring-boot doesn't offer this functionality, no big deal, we're going to deploy that war on its own tomcat, but it would be handy if it could be.
Thanks
Update
Just to clear better, I have an already running Spring Application standalone server, with its own embedded Tomcat.
Inside the embedded Tomcat I plugged some #Controllers I developed.
Then I was also able to map a third-party servlet using a ServletRegistrationBean (mapped to /servlet-path).
Now I'd like to do something similar with another war that contains a full fledged web application (it's a vaadin/spring 3.2 application with its own libraries, jsps, static resources ...) and would like to map it to (say) /war-path.
I would like to drop the war in a well known location and deploy it into tomcar with a (say) WarRegistrationBean that would let Tomcat handle all the classloading hurdles (as I mentioned, the war is using spring 3.2 while I'm using 4.0 with spring boot, ...).
I suspect that this last feature is not supported by spring-boot or - possibly - even out of scope for the project itself.
You can manually enhance a war archive by adding the stuff that the boot plugin does (classes from the loader and some META-INF information). Easiest would be to simply enhance an "empty" war, and then merge it with the target one (by exploding them both and re-jarring). The only thing you'd need to add might be a main class.
It's still a gap in the Boot tooling. If you think it needs filling please raise an issue and/or send some code.

Spring with maven-shade-plugin

I am trying to use to versions of spring in the same application: the first one is a webapp with spring 2.6 and the second it a jar client, with spring 4.0.2. The client communicates with another application and will be a dependency for the webapp. The problem is that the classloader will just load one time the common classes from spring and it will certainly fail.
I tried to use ElasticSearch aproach of using shaded dependencies(maven shade plugin) and relocate spring from the client to a different package (from org.springframework to my.springframework) and the uber jar seems to be constructed fine.
The issue is that Spring is based on spring.schemas and spring.handlers for validating xml config files and loads this files from classpath (META-INF folder and this paths are hardcoded in Spring code - e.q. PluggableSchemaResolver). I modified this files to point from org.srpingframework to my.springframework.
At runtime it seems that the classloader reads these files from the webapp, which has this files but with the real spring path and the exception is something like
org.realsearch.springframework.beans.FatalBeanException: Class [org.springframework.context.config.ContextNamespaceHandler] for namespace [http://www.springframework.org/schema/context] does not implement the [my.springframework.beans.factory.xml.NamespaceHandler] interface.
To me it seems that is impossible to achieve what I am trying (use tho spring versions in the same application with one of them relocated). Any ideas here? Am I wright?:d

Resources