I have a set of bundles deployed in Karaf and exposing a number of OSGi services which I would like to be able to lookup and call remotely, from an application running on a (possibly) different machine and in a non-OSGi container. My initial though was to use JNDI lookup to get the services I want however I understand from an earlier stackoverflow post that this might not be supported (I say might since I haven't been able to find any information on whether anything has changed on the Aries JNDI implementation in the past year). In that case I guess my other options would be to use CXF to expose a JAX-WS or JAX-RS API for my services.
Is my understanding of the situation correct? Is JNDI lookup really not an option in my case? Are there any other alternatives I have not thought of?
A simple jndi lookup will not work. OSGi services are not suitable for remoting per se. So even if you can get the jndi object in some way you can not call it.
Possible solutions are manual cxf proxies and endpoints like you already found and Distributed OSGi. See CXF-DOSGi and Eclipse ECF. Both can offer transaparent service calls from one OSGi framework to another. DOSGi is ideal if you also use OSGi on the client side.
At least in case of CXF DOSGi it is also possible to use DOSGi on the server side and a normal CXF client on the client side. So you can keep the effort on the server side minimal.
See also this tutorial for CXF DOSGi
You need a Remote Services implementation. See https://en.wikipedia.org/w/index.php?title=OSGi_Specification_Implementations for a list.
Related
We have been building two suites of applications for the last 10 years using Spring as our dependency injection. We also use spring-batch and spring-amqp. We are now looking to move to OSGI so that our monolithic applications can be separated into bundles so that we can be more agile. The two suites are web applications and are deployed as two separate war files. We are looking to use Apache Karaf as our OSGI runtime.
Spring-DM is dead and it appears that we are going to have to convert EVERYTHING to use Blueprint for our dependency injection.
My question is how do we do this incrementally? It will be close to impossible to convert all of this over at once. It seems like one bundle should still be able to use Spring DI and have it's own application context as long as we take the responsibility to expose any services that we want to the service registry in the bundle activator, but I'm not sure if there is some kind of magic that we would lose like transaction management.
Any guidance on this would be really appreciated.
You might want to consider to make the problem appear even larger and switch to DS instead of Blueprint ... To take truly advantage of the OSGi model, DS is far superior to Blueprint in all aspects. In reality, after the first hurdle, you'll make much more progress and your gains will be higher. Though Blueprint made Spring available on OSGi, it never 'got' OSGi.
For strategy, keep your Spring app alive as a single bundle and move things out gradually. I.e. the elephant approach.
The biggest gain that OSGi provides can be summarized as follows:
Make sure modules have service APIs that ONLY handle collaboration. I.e. each service API should be a story/scenario how the actors work together, not how they come into existence and are configured.
Let Configuration Admin to the configuration work. I.e. never expose configuration APIs. In OSGi, you register instances, not things that still need to be configured.
Make sure you really understand the OSGi model with services. You might want to take a look at OSGi enRoute that leverages OSGi to the hilt.
I propose you take a look at the blueprint-maven-plugin. It allows to use a subset of CDI and JEE annoations to define injections as well as transactions and persistence. The plugin creates blueprint xml at build time which can then be executed by karaf. The big advantage is that these annotations are also supported by spring. So you can transition and in parallel release to production using spring.
I have a complete example here Annotation based blueprint and JPA.
Using this plugin I migrated a medium sized project while it was developed and released in parallel. If you need further advice while using the plugin I can surely help.
I am considering writing a new set of applications using OSGi, but they will need to interact heavily with existing non-OSGi applications.
To clarify, the new applications will need to call into existing non-OSGi code bases maintained by other teams (usually propriety services of varying protocols), and new non-OSGi applications will need to call the new OSGi services.
I am not seeing much documentation for how to do this.
Can someone please point me to the correct steps
It sounds like you want to embed OSGi into a larger application. A good starting point for this is a blog post I wrote some time ago: http://njbartlett.name/2011/07/03/embedding-osgi.html
The trick to creating visibility between OSGi bundles and the objects "outside" OSGi is to publish and/or consume services using the system bundle's BundleContext. The embedding code must be aware of the objects from the outer application that you want to make visible into OSGi, and it should publish them as services. Be aware that you need to export the service interface packages via the system bundle exports -- how to do this is described in the blog post.
OSGi services are only for communications inside the same JVM process. So I guess you want to communicate between processes. In this case you have all the usual remoting protocols like SOAP, Rest, RMI. On the OSGi side you can bridge from OSGi services to offering SOAP or REST endpoints using Distributed OSGi (DOSGi).
I am currently working on an enterprise application that is deployed to GlassFish. I am attempting to figure out the right way to communicate to a cassandra backend from within an EJB that has been deployed to GlassFish 3.1. I would prefere to use Pelops to talk to Cassandra.
Disclaimer: I am new to Java EE and the concepts behind enterprise app servers and EJBs; one of the purposes of this project is to learn these topics. This is out of scope of this question as I am really just looking to be pointed in the right direction for best practices or where I should go to find best practices; so far google has not been very helpful/consistent on this topic.
More specifically, should I be thinking about writing a JCA connector for cassandra? Using a singleton EJB that talks to cassandra via Pelops? Just use pelops directly in my EJBs? (though I thought your not supposed to create socket connections in ejbs) Something else entirely?
The EJB spec prohibits EJBs from opening server sockets, but not sockets. However, it does also prohibit EJBs from creating threads. Does Pelops (or Hector) create threads to handle its pooling?
The letter of the law aside, since both those libraries do pooling, they definitely feel like something that belongs in the resource adapter layer to me. I would be nervous about EJBs, whose lifecycle is controlled by the container, and is potentially quite short, hanging on to a resource like a connection pool whose lifecycle is somewhat independent, and should be longer.
That said, most implementations of EJB are quite forgiving, so whether the use of Pelops/Hector directly from EJBs is architecturally right or not, it is very likely that it will work.
If i had all the time in the world, i would write a resource adapter wrapping one or the other of those libraries. However, that would be a considerable investment of resources in pursuit of a negligible practical return.
we are developing a similar application where I work now, even if we do not implement EJB, we deploy a backend to Glassfish 3.1 and internally we have created a small library that talks to Cassandra.
Right now the most used library for connecting and working with Cassandra is Hector:
https://github.com/rantav/hector
It is very actively developed. I have never seen it in use inside an EJB, but I used it and it is very solid. Do not how Pelops is developed though.
What we have developed here is a very custom application tailored to our needs, that is why we didn't use Hector in the first place.
As long as you use client sockets in EJB, you should be safe, the restriction on EJB is for server socket that should be handled by the app server. But if you have other needs, you should write your JCA.
I've been reading/learning more about Spring lately, and how one would use Spring in combination with other open-source tools like Tomcat and Hibernate. I'm evaluating whether or not Spring MVC could be a possible replacement technology for the project I work on, which uses WebLogic and a LOT of custom-rolled Java EE code. The thing is, I've always suspected that our solution is over-engineered and WAY more complex than it needs to be. Amazingly, it's 2009, and yet, we're writing our own transaction-handling and thread-pooling classes. And it's not like we're Amazon, eBay, or Google, if you know what I mean. Thus, I'm investigating a "simpler is better" option.
So here's my question: I'd like to hear opinions on how you make the decision that a full-blown Java EE application server is necessary, or not. How do you "measure" the size/load/demand on a Java EE app? Number of concurrent users? Total daily transactions? How "heavy" does an app need to get before you throw up your hands in surrender and say, "OK, Tomcat just isn't cutting it, we need JBoss/WebLogic/WebSphere"?
I don't think that the decision to use a full-fledged Java EE server or not should be based on number of users or transactions. Rather it should be based on whether you need the functionality.
In my current project we're actually moving away from JBoss to vanilla Tomcat because we realized we weren't using any of the Java EE functionality beyond basic servlets anyway. We are, however, using Spring. Between Spring's basic object management, transaction handling and JDBC capabilities, we aren't seeing a compelling need for EJB. We currently use Struts 2 rather than Spring's MVC, but I've heard great things about that. At any rate, Spring integrates well with a number of Java web frameworks.
Spring does not attempt to replace certain advanced parts of the JavaEE spec, such as JMS and JTA. Instead, it builds on those, making them consistent with the "Spring way", and generally making them easier to use.
If your application requires the power of the likes of JMS and JTA, then you can easily use them via Spring. Not a problem with that.
Google open sources a lot of their code. If you're writing low-level things yourself, instead of implementing code that's already written, you're often overthinking the problem.
Back to the actual question, Walmart.com, etrade.com, The Weather Channel and quite a few others just use Tomcat. Marketing and sales guys from IBM would have you believe different, perhaps, but there's no upper limit on Tomcat.
Except for EJB, I'm not sure what Tomcat is missing, and I'm not a fan of EJB.
What tomcat does not offer apart from the more exotic elements of Java EE is session beans (aka EJBs). Session beans allow you to isolate your processing efficiently. So you could have one box for the front end, another for the session beans (business logic) and another for the database.
You would want to do this for at least 2 reasons:
Performance; You're finding that one box to handle everything is loading the box too much. Separating the different layers onto different boxes would allow you to scale out. Session beans are also able to load balance at a more fine grained level. Tomcat and other web services of that ilk don't have clustering out of the box.
Flexibility; Now that you've moved your business logic into its own environment you could develop an alternate front end which used the same layer, but say, was a thick client front end for example. Or maybe other contexts would like to make use of the session beans.
Though I should probably point out that if you use web services to communicate with that middle tier, it could also be on tomcat!
The only reason to use a full blown Java EE server is if you need distributed XA transactions, if you don't need XA transactions then you can use Spring + JPA + Tomcat + Bean Validation + JSTL + EL + JSP + Java Mail.
Also a Java EE server is supposed to implement JMS but it does not make sense to run the JMS server in the same VM as the rest of the app server so if you need JMS you should have a separate JMS server.
I strongly disagree with all answers given here.
Everything can be added to Tomcat, including EJB, CDI, JTA, Bean Validation, JAX-RS, etc.
The question is: do you want this? Do you want to assemble all those dependencies in the right versions and test that it all works together, when others have already done this?
Let's be clear: nobody uses only Tomcat! Everyone always adds a web framework, an ioc container, an orm, a transaction manager, web services, etc etc
Lightweight Java EE servers like TomEE already include all of that and makes the full stack experience of having all those things integrated so much better.
Maybe this can be of interest:
http://onjava.com/onjava/2006/02/08/j2ee-without-application-server.html
HTH
Is there a way to call an EJB that is served through WebSphere (iiop://host:port/ejbName) from a vanilla JRE (like Sun). A lot of people have been telling me that this type of architecture relies in a homogenous environment. Thoughts?
Yes, this is possible. You have to create something called a thin client. It has limitations on JNDI lookups due to not being part of the container environment, so fully qualified names have to be used.
Just search for "thin client ibm ejb" on google. Unfortunately, I don't have the link to the appropriate libraries (for WAS 6) here, they are at work.
Although it’s possible, I wouldn’t recommend it because you’re asking for troubles using RMI-IIOP in a heterogeneous environment.
My approach would be to expose the EJB as a web service and consume at the client.