Is it possible to start up an external spring-boot application programmatically - java

I have created a rest application using spring-boot 2.0.3. From an other maven module (in a different multi module pom), I have an integration test that tests that data sent to the running rest application is processed.
Is it possible to run this spring-boot application programatically? I cannot use the simple #SpringBootTest-annotation as the spring-boot application is not in the same maven multi module.

I would recommend using mockito to mock a request to your rest endpoint with some data, and testing that your other application tries to send the correct data to the endpoint.
This way both applications are tested independently and do not have dependencies at each other. This provides the benefit of being able to substitute one of these applications with another if necessary. Also it provides a good separation. This is important because when you (or someone else) wants to use your REST application they do not use your other application so it is very important that the REST application is tested with static data written in your tests and is not dependent on the output of another application. Since REST applications are meant to be independent.
However, when you do want to test it this way you could try to include your other application in the classpath.

The thing is "loose coupling". It is technical possible, but not recommended. The build itself has numerous tests using where mocking with Mockito is essential.
An integration test module, ala cucumber.io, should be created which will cover the functionality of the running module.
This is the main-point of the accepted answer.

Related

Java Spring Boot MVC and CLI API in the same project

Java Spring Boot MVC and CLI API in the same project
I have implemented a web app using Spring Boot MVC and I now I need to add an API whose functions can be called from a cronjob.
I would like to use Entity and Repository classes implemented in my Web app. I was thinking about creating a new main class which implements
CommandLineRunner interface and then create separate JARS for Web and CLI applications and run them independently. Is this a good approach?
Do you have any suggestion about the architecture?
Thanks
Concur with comment from #jb-nizet - cron is really just another client of your application, and using a (bash,etc.) script wrapping curl, httpie, or wget to call the controller is a good solution.
Advantages include:
can be called remotely
doesn't add complexity to the application
application boundary/interface remains the same
doesn't add a new application (except a relatively trivial script)
not tied to cron - could be almost any other application
Considerations:
authentication (if needed) and the management of credentials in the script/cron
if all methods/actions needed for cron are new and different to existing functions in the web app, do they make sense to be encoded in the webapp?

Self contained jar with Camel and Web Interface?

I have had lots of trobule trying to get my head around how to solve this scenario:
We have an integration application that uses Camel for integration. This application also has a REST Api that exposes some services providing information about the application, for instance listing the active routes etc.
I have created a user interface for this using AngularJS that connects to these rest services. My main problem is how can I package this application as a self contained jar-file that provides the user interface and all the camel integration.
My working theory: Use a separate Jetty server to serve the Angular JS files and let Camel expose the REST services. The problem with this is CORS since the REST services reside on another port than the jetty server serving the Web UI.
Some requirements for the solution:
Must be a single self contained jar-file.
The camel integration is the main purpose, the Web UI is secondary
and only used for trouble shooting. No need for a high performance
web container since the Web ui is used by only a handful of users.
I have been struggling with this for a couple of days now and it feels like I am over complicating the solution. Help on how to solve this is greatly appreciated.
You could take a look at hawtio
http://hawt.io/
as that is how we do that, hawtio is a web console for java, and has plugins for Camel. Its built using angularjs, and uses REST to communicate with the local or remote Java JVMs. To make the REST calls easier we use Jolokia.
Jolokia requires an agent to be embedded in the JVM, eg where Camel runs. Then that helps with CORS et all. http://jolokia.org/reference/html/security.html#d0e2490

Spring environments difference

I keep on studing Spring, and find Spring environment comparison as a very obscure topic. It's very difficult (IMHO) to find something intelligible on the topic.
I've got a vague understanding of the intention of each of Spring environment (mentioned below), but can't grasp the difference between them. I mean, I understand that EJB environment is destined for integration with EJB framework. But has it got some extra-bonuses compared to Standalone? What bonuses? So my questions are:
Can you provide me a brief comparison of "extra-bonuses" (means additional functional abbilities except of integration with the framework) of each environment?
Can you explain me what is JUnit environment and for it's destined?
Environment types:
Standalone
Web
JUnit
EJB
The only difference between these is how you wish to deploy/run your application.
Standalone
Run your Java application via a "main" method.
Web
Deploy your application to a Java web container such as Tomcat, as a .war file.
JUnit
Run a JUnit test.
EJB
Access EJBs from your application, which will have been deployed through one of 1-3.
The difference between these environments has nothing to do with Spring. Spring is just a framework, which makes some aspects of an application easier to write.
For instance, in a web environment, Spring provides annotations which make it easy to expose methods in your classes as MVC controller methods, REST or SOAP endpoints. These are obviously things which are commonly needed in web applications.
In a JUnit test, the Spring-Test libraries enable you to wire up a Spring context into your test so that you can test how those components have been wired together. Whether you intend to deploy as a standalone or web application, you should be testing your components with JUnit, or another test framework as part of your build process.
With respect to EJBs, if you also have EJB components (not Spring) deployed, then Spring provides helpers which let you reduce the amount of code involved in locating/invoking them.

Adding a web interface (Spring MVC) to existing Java application

I have an existing Java application (Spring based) that currently does NOT have a web interface, nor does it run in a web container. It packages up nicely with a start program and just works.
What I need to do is add an administrative web interface for some administrative type things, retrieving real time metrics, and perhaps some graphs to give the users a warm fuzzy feeling knowing that everything is working. As we are a Spring shop, and some of our web applications already use Spring MVC it only makes sense to us, however, I'm not happy with the suggestions I've had from our internal Spring folks on how I should procede.
What would be the ideal way to bolt on this web interface?
Convert my application to a web application and have a web container launch the application. I not too keen on this approach is the web tier is really secondary to the primary application.
Create a separate project that packages as a war, embed Jetty in my existing app and have it load the war. I think I can use the context loader listener to make the root context of my application the parent to the web application spring context. This would involve breaking up my Maven project into 2 projects I believe. I can't use an existing web technology for communication between the web tier and the primary application as my primary application is not web enabled.
Embed Jetty and put the Spring MVC stuff directly in my app. While I've done this approach before, it does involve some ugliness - for instance exploding the JSP tag libs into my jar.
Any thoughts on some clean separation here?
Also of note, my current jar contains some utility applications which some shell scripts launch. Going a pure WAR route would make this not so easy, since I can't juse point java at my war file and choose a class to execute.
Thanks.
If it's true that web is just a minor addition the application, migrating it to WAR and deploying in servlet container might be an overkill. Embedding web server/servlet container looks much simpler, although it doesn't have to be Jetty or Tomcat. You can use web server built into JDK or write one on top of netty or even raw sockets. But that's a hell to maintain.
Yet another solution to springs to mymind when reading:
web interface for some administrative type things, retrieving real time metrics, and perhaps some graphs
Maybe you don't need an interface, but monitoring infrastructure instead? Check out JMX (Spring has great support for JMX) - and write a second web application that simply connects to your standalone Java app via JMX and displays the metrics in fancy way. Another approach is to expose JMX via Jolokia, which translates JMX to REST services.
This approach has several advantages:
monitoring API is universal, and you get it for free
you don't have to use web client, monitoring application is completely decoupled,
finally changes to your original application are minimal. Check out this proof of concept: 1, 2.
It really depends on the structure of your existing Java/Spring app and how much of an API it provides. I've done something similar to this and I approached it by creating a separate Spring MVC project and then specified the existing Java app as a JAR dependency.
This is easy with Maven (or Ivy, etc) and provides nice decoupling. The trick is to be able to write service classes in the Spring MVC app which then access data via your dependent Spring app via a simple DAO class. That's why I stated at the beginning, that it depends on the structure of your original Java app. It has to be able to provide an API for data access that you can then plug your DAO (impl) into.
If this is not easily done, then the next option I'd suggest is simply converting your Spring app to a Spring MVC app. I've worked on another app where we did this. Using Maven, its possible to specify that the build can create either a war file or a jar file (or both). So it can be deployed as either a webapp (via war) or a normal app (via jar). Yes, the jar version has a bit of bloat but its a worthwhile compromise.
The question of embedding Jetty or using Tomcat via a war file is a completely separate issue that has its pros and cons. It shouldn't affect the approach you take in architecting the web app in the first place.

Reflection Difference Between Straight Java and Grails

I'm using a set of APIs developed internally by my company to communicate with some common central services in the organization. The APIs can be configured dynamically by runtime configuration to use several transport protocols as needed by the system.
The collection of internal APIs are coupled to the IBM WebService thinclient.jar to configure and call all the necessary web services. I got the standalone prototype working smoothly, but need to integrate the functionality into several other services that are being developed in Grails.
This is where things fell apart. In the code that I've written, we just call a factory method and use that to get a client session and then proceed with our business logic. Simple. Using the debugger and digging into the API getClient() call, I can see that this gets a generic transport configuration and then binds it to a SOAP transport configuration. From here, the path differs whether it is the pure standalone Java service or the service running in the Grails app.
In the pure Java standalone, this then is bound to a
com.ibm.ws.webservice.engine.client.Service where the
initService() method is called and things work as expected.
In the Grails app, with the same Java code included, the same place
in the code calls to
com.springsource.loaded.ri.ReflectiveIntercepter and then after a
lot of back and forth in the spring-loaded API, it finally throws a
java.lang.reflect.InvocationTargetException.
Does any one have any tips or ideas on how to get the reflection in Grails to behave the same as in the straight Java?
I've tried a lot of variations to get to this point and I'm nearing the end of my rope. Ideally, it would be easiest to manage the Grails service that manages our business logic and the Java code that talks to these internal systems together, so I would prefer to get everything (Grails and my Java service code) working together. I briefly tried building a standalone JAR of my service code and all it's dependencies, but had chained dependency conflicts when trying to use that in Grails. My final option will be to stand my Java service up separately from the business logic in the Grails service and just make the calls from the Grails service to the Java service. This is less than ideal.
It's easy when you stumble into the answer... ;-)
The Grails service runs as expected if I set the run configuration in IDEA to use -noreloading option.
grails -noreloading run-app
This stops Grails/IDEA from leaving in the hooks to reload classes on the fly.
Are there any thoughts on whether this is a bug in Grails or the SpringSource Loader classes?

Categories