I'd like to run one spring boot application but have it listen on multiple ports.
The aim is to be able to let an Apache forward multiple (sub-) domains to the spring boot application (Tomcat) on different ports. Example:
example.com/** -> PORT 8080
client.example.com/** -> PORT 8090
employee.example.com/** -> PORT 8100
As far as I understood from several threads on SO, I'm best off launching multiple #SpringBootApplication Annotated classes from one main class, right? (https://stackoverflow.com/a/25870132/1510659)
What I didn't grasp yet, is how to configure each one of those applications separately.
Let's say I have launched these three Applications as shown in the linked post above:
MainExampleApplication
ClientExampleApplication
EmployeeExampleApplication
Now, for example, I want to have separate Spring Security #Configuration classes for each of these Applications, as well as #RequestMappings which might have the same value (e.g. "/").
How do I tell the #Configuration or #Controller classes which Application they are assigned to?
Or are there properties that can to be passed to the applications on startup to specify which resources are responsible for the context?
I hope I'm not going in a totally wrong direction here. I do have experience with Spring MVC and have configured some rather simplistic Spring applications - but not with multiple contexts. I'd be really glad if someone could lead me in the right direction. Thank you in advance.
UPDATE
As mentioned in iamiddy's answer and xeon's comment, I used Spring Profiles for that. I provided the SpringApplicationBuilder with a profile for each of my application contexts on startup and used the #Profile("some_profile") on the #Components that should only be available to some of the contexts.
Use Profiles it's a great spring feature, loads only beans associted with the profile.
Once that's done start your applications N times with different port and profile arguments
Ex: Here is how you would start the first one, do it for the rest to your N
java -jar -Dspring.profiles.active=production1 -Dserver.port=9000 app.jar
Related
I have a Spring Boot application (App1) that uses an embedded Tomcat. To specify the Port I added server.port=8080 to the application.properties in my main application
and it works fine.
Now I add a dependency to another Spring Boot application (App2) in the pom.xml (because in App1 I need access to the Beans from App2). App2 uses also an embedded Tomcat on a different port.
But when I run App1 it crashes because App2 want to also use the same server.port and configurations - that obviously cannot work.
Is this even possible what I want to achieve? And how would I do this that I can run both App2 in App1? If this is not possible, is it possible to access the Beans from App2 in App1?
I see two options, depending on which one suits your use case conceptually:
you have two Spring Boot applications that need to share the same code: extract this code to a separate project (a regular Java library), build it as a jar file and include into both projects as a dependency; an example could be found in the Creating a Multi Module Project guide;
you have two Spring Boot applications, one of them needs to access the functionality of another: provide and access this functionality as an API, instead of directly importing the beans. There are multiple ways to do this. For example, you could expose the bean functionality as a REST API using Spring's #RestController, and access them from the other side using RestTemplate. See the following guides: Building a RESTful Web Service, Consuming a RESTful Web Service
I have examples of both working individually, now trying to merge so that I have both capabilities / entry points.
Not surpised it is confused about the application contexts to load.
I want to know if this is even possible and if so any examples?
I know it is doable with spring boot however not wanting to move to that just yet.
I am attempting the impossible?
"Spring MVC (with embedded Jetty)" usually means an HTTP endpoint running in its own JVM (I suppose you have a main method that starts Jetty). Once you have that started, you can integrate it as any other HTTP endpoint in Spring Integration.
If you want them both to run in the same JVM, that probably means you don't want to make use of HTTP as you can invoke methods directly on your #Controllers or #Services.
Or perhaps I'm missing something here... ?
I'd go for Spring Boot. Version 1.1.6 was just released. I'm currently also migrating an "old" SI application to be based upon Spring Boot. I suggest you give http://start.spring.io a try. Migration should not be too difficult.
Is it possible to inject a bean from a web application that deploy in another server!
I declare a scenario to myself, I have two web application that use spring framework and deploy separately in different application servers (one is TOMCAT and another one is WEBLOGIC),the first application has ServiceA and the second one has ServiceB, now I want to inject ServiceB in ServieA?
I try to do this with RMI once an another one with JMS, now I am wondering that:
Is it possible with another thing?
Is there any active project about this scenario exist?
How can share application context in spring framework, is it possible?
Thanks.
Bean is just an object in JVM. You certainly cannot use an object from one JVM in another JVM straightforward.
But you can do 2 things:
Use proxies - some objects that will have the same interface but invoke somehow to the proper server as implementation.
Use service-oriented architecture (SOA). Each server should have some limited set of beans that are responsible for their functionality. And all beans can interact with each other.
Maybe OSGI is suitable for this.
Web services, JAX-RS is the simplest. But JAX-WS provides you with the tools to automatically generate the client code.
I'm reading up on JMX for the first time, and trying to see if its a feasible solution to a problem we're having on production.
We have an architecture that is constantly hitting a remote web service (managed by a different team on their own servers) and requesting data from it (we also cache from this service, but its a sticky problem where caching isn't extremely effective).
We'd like the ability to dynamically turn logging on/off at one specific point in the code, right before we hit the web service, where we can see the exact URLs/queries we're sending to the service. If we just blindly set a logging level and logged all web service requests, we'd have astronomically-large log files.
JMX seems to be the solution, where we control the logging in this section with a managed bean, and then can set that bean's state (setLoggingEnabled(boolean), etc.) remotely via some manager (probably just basic HTML adaptor).
My questions are all deployment-related:
If I write the MBean interface and impl, as well as the agent (which register MBeans and the HTML adaptor with the platform MBean server), do I compile, package & deploy those inside my main web application (WAR), or do they have to compile to their own, say, JAR and sit on the JVM beside my application?
We have a Dev, QA, Demo and Prod envrionment; is it possible to have 1 single HTML adaptor pointing to an MBean server which has different MBeans registered to it, 1 for each environment? It would be nice to have one URL to go to where you can manage beans in different environments
If the answer to my first question above is that the MBean interface, impl and agent all deploy inside your application, then is it possible to have your JMX-enabled application deployed on one server (say, Demo), but to monitor it from another server?
Thanks in advance!
How you package the MBeans is in great part a matter of portability. Will these specific services have any realistic usefulness outside the scope of this webapp ? If not, I would simply declare your webapp "JMX Manageable" and build it in. Otherwise, componentize the MBeans, put them in a jar, put the jar in the WEB-INF/lib and initialize them using a startup servlet configured in your web.xml.
For the single HTML adaptor, yes it is possible. Think of it as having Dev, QA, Demo and Prod MBeanServers, and then one Master MBeanServer. Your HTML Adaptor should render the master. Then you can use the OpenDMK cascading service to register cascades of Dev, QA, Demo and Prod in the Master. Now you will see all 5 MBeanServer's beans in the HTML adaptor display.
Does that answer your third question ?
JMX is a technology used for remote management of your application and for a situation for example when you want to change a configuration without a restart is the most proper use.
But in your case, I don't see why you would need JMX. For example if you use Log4j for your logging you could configure a file watchdog and just change logging to the lowest possible level. I.e. to debug. This does not require a restart and IMHO that should have been your initial design in the first place i.e. work arround loggers and levels. Right now, it is not clear what you mean and what happens with setLoggingEnable.
In any case, the managed bean is supposed to be deployed with your application and if you are using Spring you are in luck since it offers a really nice integration with JMX and you could deploy your spring beans as managed beans.
Finally when you connect to your process you will see the managed beans running for that JVM. So I am not sure what exactly you mean with point 2.
Anyway I hope this helps a little
I'm currently developing a small EJB application running on IBM Websphere Application Server 7 (Java EE 5). The app mainly consists of one MDB listening for incoming MQ messages which are transformed and stored in a DB. Currently I'm using a lot of Singleton/Factories to share configurations, mappings, datasource lookups etc. But this actually leads to some very hard to test code. The solution might be using a (simple) DI framework like guice/spring to inject the different instances. The question is: Where to place the initialization/ setup code? Where is the main entry point of the application? How can I inject instances into the MDBs?
it might be worth looking at backing off from using Guice, and trying to work with the injection mechanisms already available with Java EE 5.
Regarding finding a suitable "startup point", unfortunately the EJB specification does not define a way where you can have a bean run at startup. However, the web profile of the EE spec does have one -- you can add a WAR to your application, and set a servlet listener component:
http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletContextListener.html
You can set this to start whenever the application is loaded and started by the container (WebSphere). Watch out for classloader issues though.
Using Spring, you can do it via EJB3 interceptors, see http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ejb.html#ejb-implementation-ejb3
Useful info on caveats are in the javadoc, make sure you read it: http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/ejb/interceptor/SpringBeanAutowiringInterceptor.html