What are the important motivations for upgrading from EJB2.0 remoting to Spring remoting using HTTPInvoker?
The one that I found was that in EJB2.0, the client code has to do jndi lookups and on the server side, we need to write extra classes and interfaces(remote,home).
In Spring HTTPInvoker, we just configure the remote EJB bean as a service and we are good to go.
Just wondering if there are other benefits except this one.
If this is the only benefit, how to decide whether to go for web services or HTTPInvoker?
Spring's HTTPInvoker is a very simple RPC-over-HTTP mechanism, using standard java serialization. If that meets your requirements, then by all means use it.
However, it falls a long way short of EJB-style remoting, which as well as being more efficient (HTTP remoting is not very performant), adds facilities such as transactions and security. Both of these can be provided by Spring, but it means additional wiring and configuration.
As far as deciding between HTTPInvoker and proper Web Services, the former is highly proprietary (both ends must be Spring), and tightly couples the client with the server (they have to be serialization-compatible). Proper web-services are standards-compliant and client-agnostic (if done properly).
Related
We are trying to split a big monolithic J2EE application into a set of modules to provide unified business logic for all web application clients.
Our goal is to have smaller and more specialized business modules that can be used in any combination by many distinct web applications. This way we expect the applications get easier to maintain individually (compared to the now heavily coupled monolithic one).
We are planning to arrange it like the following diagram:
Where Web Apps call module services on the upper layer to handle business logic through method calls (RMI was the intended protocol but we are open to other options).
J2EE makes it easy to arrange services on three tiers like this through EJB remote beans.
But we are also trying to setup these modules as spring boot applications (using the Spring Boot JPA Starter) because it makes development much more convenient.
My initial plan was to implement the modules with Spring Boot and expose a thin layer of EJB beans as proxies to spring beans with the actual implementation of the service. EJB beans would have spring beans injected using the SpringBeanAutowiringInterceptor class as in spring v4 documentation.
But since this kind of integration was removed from spring v5 I don't know how to proceed.
They are also considering "EJB as an effectively deprecated technology now" as stated in the issue above. But for my use case I can't find a good enough alternative.
So far I have thought of the following options:
Using a custom interceptor as the issue suggests. But it looks like reinventing a discarded old wheel (if that analogy makes any sense).
Spring remoting is an alternative but it's challenging to make it work with Wildfly JNDI for RMI configuration and trying to looks like re-implementing EJB remoting.
Spring Integration I think will add too much complexity and overhead for this simple task.
Message based integration (JMS, MQTT, etc...) may not fit well because of the synchronous nature of what we are trying to achieve.
REST API calls would add a lot of boilerplate code (for serialization and deserialization of objects into JSON, endpoints configuration and so on) and also add some ovehead because the HTTP handling.
Our goals, in this order of priority, are:
Make this integration as solid and fail-proof as possible.
Make calls to business logic from the web layer to the service layer as simple as possible.
Have as little overhead as possible.
With all that said which of those five options mentioned (or maybe another one I haven't considered) would be the best way and why?
This is a rather generic question but would you use use JAX-RS to communicate between two server services running on potentially two different hosts (leveraging the Resteasy client)?
Or would you stick to the more traditional EJB remote invocation?
I'm a bit worried about the following potential issues:
- maintaining a pool of Http connections - will be per client and not global to the application server
- no optimisation if both services are on the same host (EJB invocations would be local in this case)
- authorisation (credentials): managed by the application itself when configuring the RestClient vs. container managed for EJB
- what else?
Any feedback?
Thanks for your help.
Most implementations of JAX-RS have a client API, so the setup should be easy if you share annotated interfaces between the two projects. Communication may be slower than with other solutions because you have to serialize/deserialize all parameters and responses, usually in formats like XML or JSON. I wouldn't worry to much about optimizing inter-process communication as communicating with localhost is still is way faster than with a remote machine. If you expect to have parts of this API public, REST would be the best option, regardless of performance.
If the communication will only be internal, and you really care about performance, you could use a more specialized framework like Protocol Buffers. JAX-RS is a JavaEE Standard and REST are well established though, which might be more important than performance. For more large, complex, JavaEE based systems, a common solution would be to use messaging and integration frameworks like Apache ActiveMQ and Apache Camel, which also support JAX-WS/JAX-RS frameworks like Apache CXF and should have optimization for inter-process communication. For small applications this seems like overkill though.
I never used EJB so I can't really compare it to other solutions. From what I've heard, the whole EJB approach is way to complex and hasn't been adapted very well in the industry. I also would worry a bit about cross platform compatibility.
I would choose a solution that isn't too complex and easy to setup. One last thing: In my experience, when you expect two application to be running on the same machine so often that you want to optimize it, they probably should have been combined in a single server application in the first place, or maybe one of the servers should have been an optional plugin for the other one.
I am working on a desktop Java application that is supposed to connect to an Oracle database via a proxy which can be a Servlet or an EJB or something else that you can suggest.
My question is that what architecture should be used?
Simple Servlets as proxy between client and database, that connects to the database and sends results back to the client.
An enterprise application with EJBs and remote interfaces to access the database
Any other options that I haven't thought of.
Thanks
Depending on how scalable you want the solution to be, you can make a choice.
EJB (3) can make a good choice but then you need a full blown app server.
You can connect directly using jdbc but that will expose url of db (expose as in every client desktop app will make a connection to the DB. you can not pool, and lose lot of flexibilities). I would not recommend going this path unless your app is really a simple one.
You can create a servlet to act as proxy but its tedious and not as scalable. You will have to write lot of code at both ends
What i would recommend is creating a REST based service that performs desired operations on the DB and consume this in your desktop app.
Start off simple. I would begin with a simple servlet/JDBC-based solution and get the system working end-to-end. From that point, consider:
do you want to make use of conenction pooling (most likely). Consider C3P0 / Apache DBCP
do you want to embrace a framework like Spring ? You can migrate to this gradually, and start with using the servlet MVC capabilities, IoC etc. and use more complex solutions as you require
Do you want to use an ORM ? Do you have complex object graphs that you're persisting/querying, and will an ORM simplify your development ?
If you do decide to take this approach, make sure your architecture is well-layered, so you can swap out (say) raw JDBC in favour of an ORM, and that your development is test-driven, such that you have sufficient test cases to confirm that your solution works whilst you're performing the above migrations.
Note that you may never finalise on a solution. As your requirements change, and your application scales, you'll likely want to swap in/out the technology most suitable for your current requirements. Consequently the architecture of your app is more important than the particular toolset that you choose.
Direct usage of JDBC through some ORM (Hibernate for example) ?
If you're developing a stand-alone application, better keep it simple. In order to use ORM or other frameworks you don't need a J2EE App Server (and all the complexity it takes with it).
If you need to exchange huge amounts of data between the DB and the application, just forget about EJBs, Servlets and Web Services, and just go with Hibernate (or directly with plain old JDBC).
A REST based Web Services solution may be good, as long as you don't have complex data, and high numbers (try to profile how long does it takes to actually unmarshal SOAP messages back and to java objects).
I have had a great deal of success with using Spring-remoting and a servlet based approach. This is a great setup for development as well, since you can easily test your code without deploying to an web container.
You start by defining a service interface to retrieve/store your data (POJO's).
Create the implementation, which can use ORM, straight JDBC or some pooling library (container provided or 3rd party). This is irrelevant to the remote deployment.
Develop your application which uses this service directly (no deployment to a server).
When you are satisfied with everything, wrap your implementation in a war and deploy with the Spring DispatcherServlet. If you use maven, it can be done via the war plugin
Configure the desktop to use the service via Spring remoting.
I have found the ability to easily develop the code by running the service as part of the application to be a huge advantage over developing/debugging something running on a server. I have used this approach both with and without an EJB, although the EJB was still accessed via the servlet in our particular case. Only service to service calls used the EJB directly (also using Spring remoting).
I'm trying to understand how the JAAS principal propagates to the Business/EJB tier from web tier.
I've read that the if the roles/realm is configured in login-config & security-context of web.xml then the servlet container will also transparently pass the authenticated principal to the EJB Tier.
Two questions
1.) First & more importantly is that true ? Without any intervention from the developer !
2.) And secondly any idea how that works under the hood.
yes it's true. that's generally the point of ejb, to take the "hard" stuff out of the hands of the developer (e.g. security, transactions, robustness, multithreading, etc.)
it's implementation dependent. i know that in jboss (at least 4.x and before), remote method calls used a custom serialization protocol which had an additional Map of arbitrary information which could be sent along with the request. in this was the auth info as well as other stuff to support clustering. for local method calls i believe they use stuff like ThreadLocals.
There are various "context" pieces of information that get propagated in EJB calls, once you get inside the EJB layer and start doing EJB-EJB calls then Transactions would be an example. Some containers allow you to create your own such context objects too.
Thread-local storage can be used within a process, but generally just assume that the container is in charge and can do the right thing - the actual technique is implementation specific.
Regarding your first question - yes.
Regarding your second question - are you familiar for example with EJB3 interceptors?
The container create proxied objects with "interception code" for the beans,
and in addition the container can track other annotations on the methods and the bean class, for example, to detect the #PostConstruct annotation.
Using the role definition, it can check the configuration (either login-config.xml at older versions of jboss, or standalone.xml in JBoss AS 7 at standalone configuration) and understand what is the definition per each role.
JAAS is used in order to provide you abstraction layer over authentication and authorization.
One of the concepts behind JAAS is login module - it provides you "protocol specific" code that takes care of the actual authorization and authentication.
For example, I'm using in this way Krb5LoginModule to use kerberos.
The Principal propagates to the EJB tier from web tier is configured through the login-config in the web.xml as you had surmised for the most part.
How it is implemented is implementation dependent. The user/group data is also implementation dependent and is configured as part of the application server.
However, one of they ways this is done is through an implementation of the JASPIC provider which is a standard way of obtaining the Principal. Using this allows you to have a different authentication path compared to the standard form login, basic authentication or certificate authentication provided by WEB-INF/web.xml but it is a little bit more work.
JASPIC authentication paths allow more complex scenarios such as header based authentication or two-factor or OpenID. The user database "usually" does not need to be tied to the one in the application server. I say "usually" because WebSphere Application Server ties the authentication to a user configured on the server.
A little context: I would like to separate the Java application I'm writing into a more or less typical server-client model. I would provide a "server" which takes care of business logic and persistence, but write it in a very service oriented fashion. Any front-end code (GUI) would then call upon the server to provide the functionality in a user friendly fashion.
As I'm writing the application using Spring (and an ORM framework), it would make sense to explore the usual suspects to expose the server functionality, with the usual suspects being RMI, Spring HTTP, Hessian, web services, etc (the Spring natively supported options). These are well well documented, both in reference documentation and on here.
However, for the actual question: are there any less obvious, more exotic options I could consider to use for exposing my server services?
It's important (as always) to get the right balance between ease of use (from a front-end POV), performance and scalability. For example; since I've thought about providing the Spring-BlazeDS integration in the server any way (for Flex/AS3 clients), it dawned on me that BlazeDS provides a Java-native API for calling AMF services.
Any pointers are much appreciated.
I would recommend BlazeDS if you have a Flex front end and Spring HTTP if not. Both eliminate the non-productive work introduced by having to translate XML to objects and back again.
Spring HTTP is especially attractive because you can write POJO Spring service interfaces just as you always do, deferring the choice to expose via HTTP remoting until the end. You keep your options open that way. If you decide that Spring web services work better for you later on, you can keep re-using the same POJO Spring interface.