Java EE deployment issue - java

I'm running into some issues in deploying my Java EE application, and could use some advice.
I have 3 components to deploy:
Integration layer (Data): POJOs and CDI Beans - JAR file
Application layer (BL): EJBs, CDI Beans and POJOs - JAR file
Presentation layer: Servlets and such - WAR file
Optimally, I would like to be able to deploy both the integration and application layer JARs in the same Java EE server, but as separate JARs (since I might want to change the hardware configuration later on and separate them into two different servers on two separate machines).
The problem, is that I'm unable to get the CDI injection from the integration layer JAR to the application layer JAR to work. The server says (and probably rightfully so) that it's impossible to resolve the injections.
So far I came up with these possible solutions:
Package the two JARs into a single EAR file (maybe throw in the WAR as well ...), and deploy that
Use JNDI between the different layers (possibly create a CDI producer to do a generic injection based on JNDI names or something like that)
In the integration layer, make the objects being injected into the application layer (the DAOs) EJBs instead of CDI beans
I don't like either of these solutions (especially the last), since they restrict my future deployment options. The second solution does not restrict me, but it might become tedious at some point (when I accumulate a lot of code).
Finally, my question is:
Is there an option I didn't find yet, that would allow me to deploy the two JARs on the same server with the CDI injections working ? Possibly something that would still work if at some point I separate the JARs into different servers ?

Yes, there are other options as well.
Use a java EE container that supports OSGi as well, and use OSGi interface for your deployment dependencies. At least Websphere, Glassfish, JBoss (with jbosgi installed), Jonas support deploying OSGi bundles. This means your modules should be converted into OSGi bundles.
Use a container-specific extension that allows modules to communicate between each other. JBoss as jboss-deployment-structure.xml that you can use to have a dependency to another deployment.
Use a server-provided shared classpath for your dependencies. Wouldn't really recommend this.
My vote would go for OSGi.
None of them will work by themselves however if you deploy packages to different servers. A remote technology like remote EJBs, remote JNDI lookups, Spring remoting, HTTP-based api, CORBA or similar is needed between different servers. In Java EE, EJB is the de-facto standard for this, but Spring remoting is not bad either.
Update: you added that you use TomEE servers. Indeed TomEE won't support the first two options I mentioned. I would use EJB in that case - the fact that you're using EJBs can be abstracted away from the business layer using an EJB delegate, and you could use EJB (stateless session bean) only for the interface part, leaving your DAOs as POJOs.

not sure what your goal is but deploying a war is fine, can even be done manually with these commands:
mkdir -p webapps/myapp/WEB-INF/lib
cp myjar*.jar webapps/myapp/WEB-INF/lib/
If your goal is to be able to split them you can use TomEE skinny war feature.
Create a war with a WEB-INF/jars.txt file.
In this jars.txt put one line by dependency/jar. It can be the path to the jar or maven coordinates.
Once setup it will allow you to change jars one by one then simply restart the server. This is great when several teams work on the same binary.
There are some alternative with TomEE but this one has the advantage to be easy to change to a portable one (war).

Related

Spring Boot microservices Embedded tomcat vs External tomcat

I am building microservices(approx 15 to microservices) project for huge organization, I wants to know is it recommended to go for external tomcat with war file or just use the embedded tomcat of spring boot with jar file. Also I am facing issue after building my project on jenkins how to copy the file from jekins server to my server and run the file there and create and automatic build and deployment pipeline i.e. everytime I push the code it should be automatically deployed.
You need to identify what compels you to go for external tomcat deployment. As SpringBoot provides out of box facility to deploy within the container, it is not required to go for external tomcat deployment.
Besides, if you are going for many microservices, it will be good to have with built in springboot with embeded tomcat. Springboot also provides the facility to use undertow or jetty. I would recommend to use SpringBoot with either embeded tomcat or undertow with docker container for more flexibility.
It will be good if you provide the issues you are facing.
You can check the below link for reference.
https://dzone.com/articles/spring-boot-with-external-tomcat
I didn't encourage until today companies using Spring Boot and deploying in an external Tomcat.
If there is no requirements from your Infrastructure department, I would go with the embedded tomcat.
JARs vs WARs
I think both have their use cases, like a car vs a truck.
Getting started with jar files is definitely easier, it's provided out of the box. However, using war files in a tomcat has a few perks too:
You can use the "manager" UI to update/redeploy a webapp easely
You can monitor server status, inspect sessions, basically have a look under the hood
You can deploy/update multiple wars independently, which might be handy for larger project
...but there is definitely some learning curve to set things up, and it feels a bit ...old. So it's up to you if you want an easy "jar car" or a whole "servlet container truck". ...or you can also have multiple cars. ;) Each has ups and downs.
Pipelines
Like for any other topic, there are very different ways to achieve this. If you use an extern tomcat, you may configure a "script" user and deploy it like this (or similar):
curl -u username:pwd -d path=/something -d war=file:target/someWar.war https://someurl.com/manager/deploy
...or you can go the other way round and create Docker images, or cloud-init VMs or whatever. Or just a shell script to stop it remotely, upload it and start it.
Depending on your situation, the know how of your team mates, etc, one or the other may be easier.

Should we use ApacheCXF or EJBs for communicating the logic and web modules?

We are currently developing a web application for college and we would like some advice from a more experienced developer.
We have a backend using Hibernate to operate on a MySQL database. Another project is the web UI that uses the API delivered by the backend (registering user, fetching data associated with certain profiles etc.). We use the JSF framework (RichFaces) for the UI. Everything is built using Maven.
The technology we can't decide on is for the communication between UI and logic modules. The first option is to use ApacheCXF to provide SOAP webservices that UI can be a client of. The second option is to use EJBs to invoke backend methods from the UI module.
What approach is more widely-used? As far as we read on the Web, using EJB is faster than SOAP webservices. On the other hand, we don't have any experience with EJBs using Tomcat (we would prefer using Tomcat since it seems to be a cheaper option, however we don't know what we would have to do in order to use EJBs with Tomcat). Additionally, working with webservices since the beginning will allow us to add support for different platforms (for example, Android).
Another aspect which we are discussing is about how should the application be deployed. The alternatives we have considered right now are:
Deploy it as a single WAR project (which would solve the problem we have about communicating the UI with the backend of our application).
Deploy two WAR projects in the same server using webservices for communication between the projects. (We have a prototype using this approach deployed on a Tomcat server)
Deploy a WAR project and EJB project.
Deploy an EAR project which would contain the references to the WAR and EJB projects. (We have a prototype using this approach deployed on a Glassfish server)
The project right now is starting, so we will only be handling a couple hundreds of users right now. However, if the project succeeds we would need to deal with a couple million of users.
Any advice would be appreciated. Thanks.
Edit: So any advice about how the project should be deployed? Is it necessary to use EAR? Is there any advantage if we deploy the project as an EAR module?
Edit 2: We found the advice we needed on this thread: Deploying java applications (Tomcat/Glassfish)
First things first. I would avoid using Web Services if there's no need for it. If you feel that you might need to call this system from external programs and platforms, then go for it. Even then, I would only use the web service interface for external integration, and still have an internal EJB implementation.
EJBs are awesome for enterprise applications. I would highly recommend that you look into that. They provide support for EJB Pooling, Transactions, Aspect oriented programming, Security, Stateful sessions, Java Messaging, JNDI etc. And you can inject them directly inside a Managed Bean (JSF). You said that you will eventually handle millions of users, so I assume that you will want your application to run as fast as possible, I don't think SOAP web services will be a good fit. Remember that SOAP web services encode messages as text, so if your application will be sending binary files etc, then you'll suffer significant performance issues.
As far as deployment goes I would go with an EAR, or a WAR for the JSF and and EAR backend. you can use Injection to pull the classes you need, even remotely, from multiple web applications and other EAR apps.
I'm not sure why you say Tomcat is Cheaper. Glassfish open source edition is a fully functioning JavaEE6 Server and its free. JBoss is also JavaEE compliant and is free. both of them are used in lots of production environments. I find glassfish to be much more user friendly, and would recommend it to EJB noobs :)
I also started with Tomcat, but now I don't use it at all. why use the servlet container only, when you can have the whole shabang? hope this helps.
we use ApacheCXF at work and its has SOAP and Restful. Reliable and relatively easy to setup. I am not sure why you want to use glassfish maybe it's preference but you can implement your projects in eclipse too. It's really that is up to you and your team and the requirements and skill sets your team may have to build and support, that a side CXF webservice+apache + eclipse with maybe two war files would be a good path.
I wouldn't use web services in this case. You can use managed beans as controllers.
Put the logic into EJBs, views into rich faces and control the flow using managed beans.
If you use maven you can generate a project with the structure of EAR (war for web module and jar for ejbs). I don't remember the name of an archetype but you can find it easily.

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.

OSGi and legacy applications

I would like to use the Config Admin service to manage configuration for my services. Since I'm just starting to use OSGi, I would like to introduce it step by step. So, I would like to keep some of my applications as they are now, without executing them inside an OSGi framework. But, I would also like to be able to use the Config Admin service from these legacy applications, so they can also get configuration information as other OSGi services.
Is it possible to do with OSGi? By looking at the specs, I've found a specification for Foreign Applications Access. I don't know if it's related to my problem. If it is possible, where I can find resources about how to make my legacy applications interact with the Config Admin service.
I precise that I'm using Apache Felix in the case it's implementation specific.
Thanks
Basically what you want to have is code the can run inside as well as outside OSGi. When in OSGi you want to leverage the config admin service. Is that correct?
So a good solution for this is following the principle of dependency injection. You code should not load configs, instead it should expect the config to be injected. For example use a setter where you need a config attribute. Outside of OSGi you can use spring or hand code injections to set the configs. Inside OSGi you could use an Activator or a blueprint context. Both will be inactive when you do not run in OSGi so it does not hurt to always have them.
See my first Apache Karaf Tutorial for how this works. The tutorial only shows the setup for OSGi but it is easy to see what you would need to do outside OSGi to configure the example.
Karaf Tutorial Part 1 - Installation and First application

How is GlassFish an OSGi container?

In researching OSGi and OSGi containers, I stumbled across this SO question mentioning GlassFish as an OSGi container, and I have to say I'm quite baffled.
How is this possible?!?!
My understanding was that OGS - a Java-compliant app server - has 2 containers:
Web Container: where you deploy WAR files for web apps and services
App Container: where you deploy EJBs for business logic
Where do OSGi bundles fit into this paradigm?!? Does OGS allow you to deploy an OSGi bundle to the app container and treat it like an EJB or something? And if I'm mistaken about how OGS works please correct me! Thanks in advance!
Hmm, a rather total misunderstanding of what OSGi is ...
OSGi is a framework that allows you to organize your code so that you can built it from reusable components that can then collaborate through the service layer (no more Class.forName or XML!).
OSGi frameworks can run standalone, they run inside an application, the can run in a WAR file, and they can run inside an application server. And you can even run OSGi inside OSGi inside OSGi since it does not rely on statics anywhere.
The OSGi Alliance specifies a format for the modules (bundles) so that modules can specify their dependencies. The Alliance also specifies an API to install and manage modules. And last, it specifies a large number of interfaces that are useful when you develop applications.
Websphere, Glassfish, JBoss, Jonas, all support deploying OSGi bundles.
OSGi is a module system that allows to add/remove/upgrade different bundles, handles dependencies, provides runtime information on the status, etc.
When it comes to GlassFish (which has an Apache Felix OSGi container in it), the different features of the application server (eg HTTP server, JMS server, etc.) are implemented as bundles. There is console and web based interface for the OSGi container where you can start, install, remove services (see the PDF below)
As far as Java EE applications go, they can interact with the OSGI container too. For example, an EJB can be exported as an OSGi service and also the EJB can consume an OSGi service itself.
For more info, see http://glassfish.java.net/public/GF-OSGi-Features.pdf
Glassfish internally uses OSGi to provide the features you mentioned. Besides that you can deploy your own OSGi bundles on it. See https://wikis.oracle.com/display/GlassFish/OSGi
There is no real connection between OSGi and Java EE though. You can not yet use JavaEE in OSGi bundles on Glassfish. For this case there are first initiatives like Weld on OSGi: http://www.slideshare.net/TrevorReznik/weldosgi-injecting-easiness-in-osgi
They are not really production ready though.

Categories