Why is it a bad idea to manually wire OSGi services? - java

In order to favor certain service implementations over others, I wrote a customizable version of java.util.ServiceLoader (adds priority and enabled/disabled flag to implementations via preference files for non-OSGi code).
The client was pleased and wanted the same customization for OSGi service implementations.
The devised solution is based on calling getServiceReferences(Class<S> clazz, String filter) on BundleContext and uses a null filter to retrieve all implementations.
Nevertheless, fiddling around with OSGi on such a low level leaves a bad taste. There's much boilerplate code (e.g. mandatory subtypes of BundleActivator) and the used approach will also hinder an smooth upgrade to declarative services and some point in time.
I also read about the SERVICE_RANKING property, but compared to the preference files from the approach above, it has the drawback that each implementation sets its own ranking property and it's not possible to change the ranking afterwards.
So my question is: What are good arguments against this low-level approach? Why should declarative services be used instead?

At the core OSGi is a dynamic environment. Bundles and services can come and go at every moment (theoretically). So the only way to cope with this environment is to react on changes compared to waiting for something to happen.
For example a declarative services component will come up once all its mandatory services are present and will vanish if one goes away.
A solution based on service loader or similar will actively get the services that are available if such a service is mandatory then you will have to block until it is available. This can easily lead to deadlocks in the application.
Of course in practice the application is normally not so dynamic. In most cases this only affects the startup of the application. So in many cases the blocking behaviour can work but it will produce an application that is inherently fragile.
On the other hand if you have the problem that your application needs to run inside and outside of OSGi then DS is problematic as it relies on OSGi to be present.
Typical examples are Aapache CXF and Apache Camel. Both do not use DS and instead invented different abstractions for usage in OSGi and both sometimes have problems in OSGi exactly because of this. Still it would be difficult to improve this as they need to work outside of OSGi too.

Related

How to run Apache Sling with an enabled SecurityManager?

Did anybody run Apache Sling with an enabled Java SecurityManager? That'd need a special java.policy file to allow the actions done by all deployed bundles, and it'd be extremely helpful to have a basic version that already allows what's needed by the bundles provided with the basic Sling Starter, and to which one could add policies for additional deployed code.
I'd also be interested if someone can tell that employing the SecurityManager is infeasible in a Sling setting, perhaps due to its design properties (such as the ability to add JSPs to the JCR at runtime).
Background: If you run code of several mandants on one server, that might be neccessary to separate their code from each other. While OSGI does have some mechanisms to separate bundles from each other, it'd be trivial for malicious code to use e.g. Java reflection to grab internal stuff from services provided by other bundles. An enabled security manager might at least make that much more difficult.
(I do realize that even with a security manager it's probably quite possible for malicious code to use bugs and design flaws to get access to resources of other users on the system, and that probably the only way to seriously separate code from different mandants would be using different servers. But at least one can try to make it hard.)

How to effectively manage a bunch of jar files and their plumbing?

This is a rather high-level question so apologies if it's off-topic. I'm new to the enterprise Java world.
Suppose I have written some individual Java packages that do things like parse data feeds and store the parsed information to a queue. Another package might read from that queue and ingest those entries into a rules engine package. Tripped alerts get fed into another queue, which is polled by an alerting service (assume it's written in Python) that reads from the queue and issues emails.
As it stands I have to manually run each jar file and stick it in the background. While I could probably daemonize some or all of these services for resiliency or write some kind of service manager to do the same, this strikes me as being very amateur. Especially since I'd have to start a dozen services for this single workflow at boot.
I feel like I'm missing something, but I don't know what I don't know. Short of writing one giant, monolithic application, what should I be looking into to help me manage all these discrete components and be able to (conceptually) deliver a holistic application? I'd like to end up with some sort of hypervisor where I can click one button, it starts/stops all the above services, provides me some visibility into their status and makes sure the services are running when they should.
Is this where frameworks come into play? I see a number of them but don't know if that's just overkill, especially if I'm not actively developing a solution for that framework.
It seems you architected a system with a lot of components, and then after some time you decided to aggregate some of them because they happen to share the same programming language: Java. So, first a warning: this is not the best way to wire components together.
Also, it seems you don't know Java very well because you mix terms like package, jar and executable that are totally unrelated and distinct concepts.
However, let's assume that the current state of the art is the best possible and is immutable. Your current requirement is building a graphical interface (I guess HTTP/HTML based) to manage all the distinct components of the system written in Java. I suggest you use a single JVM, writing your components as EJB (essentially a start(), stop() and a method to query the component state that returns a custom object), and finally wire everything up with the Spring framework, that has a nice annotation-driven configuration for #Bean's.
SpringBoot also has an actuator package that simplify exposing objects. You may also find it useful to register your beans as Managed beans, and using the Hawtio framework to administer them (via a Jolokia agent).
I am not sure if you're actually using J2EE (i.e. Java Enterprise Edition). It is possible to write enterprise software also in J2SE. J2SE is not having too much available off the shelf for this, but in contrast has a lot of micro-frameworks such as Ninja, or full stack frameworks such as Play framework which work quite well, much easier to program, and performs much better than J2EE.
If you're not using J2EE, then you can go as simple as:
make one new Java project
add all the jars as dependency to that project (see the comment on Maven above by NimChimpsky)
start the classes in the jars by simply calling their constructor
This is quite a naive approach, but can serve you at this point. Of course, if you're aiming for a scalable platform, there is a lot more you need to learn first. For scalability, I suggest the Play! framework as a good start. Alternatively you can use Vert.x which has its own message queue implementation as well as support for high performance distributed caches.
The standard J2EE approach is doable (and considered "de-facto" in many oldschool enterprises) but has fundamental -flaws- or "differences" which makes a very steep learning curve and a very much non-scalable application.
It seems like you're writing your application in a microservice architecture.
You need an orchestrator.
If you are running everything in a single machine, a simple orchestrator that you probably is already running is systemd. You write systemd service description, and systemd will maintain your services according to your services description. You can specify the order the services should be brought up based on dependencies between services, restart policy if your service goes down unexpectedly, logging for stdout/stderr, etc. Note that this is the same systemd that runs the startup sequence of most modern Linux distros.
If you're running multiple machines, you can still keep using single machine orchestrator like systemd, but usually the requirement for the orchestrator will also become more complex. With multiple machines, you now have to take into account things like moving services between machines, phased roll out, etc. For these setups, there are software that adapts systemd for multi machine orchestration, like CoreOS's fleetd; and there are also standalone multi machine orchestrator like Kubernetes. Both uses docker as application container mechanism.
None of what I've described here is Java specific, which means you can use the same orchestration for Java as you used for Python or other languages or architecture.
You have to choose, As Raffaele suggested you can choose to write all your requirements into one app/service. Seems like a possible mission, using java Ejb's or using spring integration - ampqTemplate ( can write to a queue with ampqTemplate and receive the message with a dedicated listener (example).
Or choosing implementation with microservices architecture. write a service that will push to the queue another one that will contain the listener etc. a task that can be done easily with spring boot.
"One button to control them all" - in the case of a monolithic app - it's easy.
In case that you choose microservices architecture. It depends what are you needs. if its just the "start" "stop" operation I guess that that start and stop of your tomcat/other server will do. For other metrics, there is a variety of solutions. again, it depends on your needs.

Is JavaEE really portable?

I'm just implementing a JavaEE assignment I was given on an interview.
I have some prior experience with EJB, but nothing related to JMS and MDBs. So here's what I find through the numerous examples:
application servers bind their topics and queues to different JNDI names - for example topic/queue, jms
the activationConfig property is required on JBoss, while in the Sun tutorial it is not.
after starting my application, jboss warns me that my topic isn't bound (it isn't actually - I haven't bound it, but I expect it to be bound automatically - in fact, in an example for JBoss 4.0 automatic binding does seem to happen). A suggested solution is to map it in some jboss files or even use jboss-specific annotations.
This might be just JBoss, but since it is certified to implement to spec, it appears the spec doesn't specify these these things. And there all the alleged portability vanishes.
So I wonder - how come it is claimed that JavaEE is portable and you can take an ear and deploy it on another application server and it magically runs, if such extremely basic things don't appear to be portable at all.
P.S. sorry for the rant, but I'm assume I might be doing/getting something wrong, so state your opinions.
Java EE, like (almost?) any standard, is something that implementers strive to advertise adherence to but desperately don't want to adhere to.
Consider this question: how does Red hat make money? By giving things away or by selling them? If the code you wrote could be easily transferred to another Java EE application server, this would interfere with them making money from you. The solution to this is the venerable "embrace and extend" technique that has been attributed to Microsoft but in reality has been the tool of choice for commercial software vendors since the first standard was published.
If you stick strictly to the Java EE APIs in your code then JBoss (or Geronimo (or JonAS (or ...))) will run it as well as any other compliant application server with the only changes being required in the server-specific deployment descriptors. This is the embrace stage.
Each server -- the commercial ones (like JBoss) in particular! -- also tends to add extra stuff to the API to "make things easier". (To be fair these often do make things easier.) Developers -- especially those not intimately familiar with the standard APIs -- frequently fall into the trap of relying on these extra APIs without wrapping them in any way, thus allowing these extensions to inundate their code to the point that they're difficult to remove should you wish to change platforms. This is the extend stage.
Name a standard from any point in software history and you'll find people embracing and extending (to the point that when people talk about "deadly embrace" I have to forcibly move my thoughts away from vendor lock-in problems to the proper terminology). You'll also find end-users (developer or otherwise) falling for it. Java EE is no different than any other technology in this regard.
Then you factor in just how badly-worded most specifications are and ...
Joel says "all non-trivial abstractions are, to some degree, leaky." I have found this to be very applicable to JavaEE. Consider that a JMS exception may be something transient such as a full queue. This is a typical fast-producer/slow-consumer problem and ideally the producer will throttle down to match the consumer's speed. But the error may also be fatal such as an authorization failure. In the first case retries eventually succeed (usually) whereas in the second case no amount of retry will help until humans intervene to fix the authorization failure.
So what do you do in your portable program to address this? One approach is to treat every JMS exception as fatal. Close all your objects and reinitialize the program. Sort of like killing a fly with a sledgehammer but very portable. Alternatively, you can check the JMS exception to see if it's a transient or fatal error and take some appropriate action. This is much more efficient but since the JMS exceptions are provider-specific it is hardly portable. Some of my clients have taken the approach of writing vendor-specific shims which catch JMS exceptions and do vendor-appropriate things with them so that the code can be "portable" (think: software equivalent of the Hardware Abstraction Layer).
And of course, this is just exception handling. Similar issues exist across the board. Consider reconnection details. Some transports bubble up a connection failure to the application or container. Some hide it away with the idea that the code should not need to know about this. But the reality is that virtually all messaging applications will need to provide an alert or log entry if the network is permanently down. You would not want the app to just hang forever if the network failed, right? So ultimately even an app running on a transport that provides transparent reconnect needs to code for connection failures. The specific features and behavior of the transport provider will leak up through the abstraction of JMS.
For my money, JavaEE makes the skills portable across transport providers. The application needs to be aware enough of the underlying transport provider to deal with the abstractions that bubble up to the surface. To the extent that you can avoid the leaks the app is portable, but no further.
That's just a partial answer but Java EE 6, more precisely EJB 3.1, finally specifies Portable Global JNDI Names. Prior to Java EE 6, JNDI naming wasn't standardized and each app server vendor was using its own rules which was indeed bad for portability (a kind of vendor lock in). Consequently, in the J2EE 1.4 world, if you wanted to ease the portability of your enterprise application it was necessary to implement various strategies, typically in your ServiceLocator class. The introduction of dependency injection in Java EE 5 reduced the need for lookups and somehow "improved" the portability but still, no standard for when JNDI lookups are needed and polyglot ServiceLocator are still required.
The core EE application can run unchanged. The external configuration is application server specific.

Why and when to use EJB-based web services?

To transfer data from one system to another, through data interface, by web services, we normally get a result set by SQL query, and format them as a web service endpoint, and allow it to be retrieved by another side.
With EJB 3.0, it seems we can replace the result set by stateless session bean. So are there any advantages over the SQL-based web services? And when should we use it?
This is a very broad question on the system architect level. I will try to answer with my best knowledge without starting a flame war (FYI, I have used both ejb and spring).
As you know, building a stable/robust software application requires many building blocks, such as logging, connection pool, etc. Usually, you can find libraries of these building blocks, but not all of them have common api, so they may require integration. In the worst case, you may have to lock into some vendors. The main idea of EJB 3 (or Java EE) is to provide a more complete set of building blocks (via API, annotation or config), so developers can start working on the core business logic right away with an industry standard API/spec/config without training on the proprietary APIs. Additionally, you can change vendor without changing your codes since API/config are really the industry standard (well, your mileage may vary a lot in the real life. hopefully, the new Java EE will fix it).
Your application may already have some of the main elements that EJB 3 already provides. However, EJB 3 promises to provide more such as ORM mapping, RMI, Load balancing, failover, transactions, dynamic redeployment, logging, system management, thread managing, resource pooling (db connection), security, caching.
As you have an working application already, you can really consider if it is worth of your efford to migrate your codes to a standard system to gain more functionality vs integrate new functionality individually. Additionally, EJB 3.0 (or Java EE) is not really the framework that you can pick. You can also look into other framework, such as Spring.
My suggestion is to really figure what your system requirements, and then pick the right technologies instead of picking up the coolest technologies first.
Good luck

What remoting approach for Java application would you recommend?

I wonder how is the best way to integrate Java modules developed as separate J(2)EE applications. Each of those modules exposes Java interfaces. The POJO entities (Hibernate) are being used along with those Java interfaces, there is no DTO objects. What would be the best way to integrate those modules i.e. one module calling the other module interface remotely?
I was thinking about: EJB3, Hessian, SOAP, JMS. there are pros and cons of each of the approaches.
Folks, what is your opinion or your experiences?
Having dabbled with a few of the remoting technologies and found them universally unfun I would now use Spring remoting as an abstraction from the implementation.
It allows you to concentrate on writing your functionality and let Spring handle the remote part with some config. you have the choice of several implementations (RMI, Spring's HTTP invoker, Hessian, Burlap and JMS). The abstraction means you can pick one implementation and simply swap it if your needs change.
See the SpringSource docs for more information.
The standard approach would be to use plain RMI between the various service components but this brings issues of sharing your Java interfaces and versioning changes to your domain model especially if you have lots of components using the same classes.
Are you really running each service in a separate VM? If these EJBs are always talking to each other then you're best off putting them into the same VM and avoiding any remote procedure calls as these services can use their LocalInterfaces.
The other thing that may bite you is using Hibernate POJOs. You may think that these are simple POJOs but behind the scenes Hibernate has been busy with CGLib trying to do things like allow lazy initialization. If these beans are serialzed and passed over remote boundaries then you may end up with odd Hibernate Exception getting thown. Personally I'd prefer to create simple DTOs or write the POJOs out as XML to pass between components. My colleagues would go one step further and write custom wire protocols for transferring the data for performance reasons.
Recently I have been using the MULE ESB to integrate various service components. It's quite nice as you can have a mix of RMI, sockets, web services etc without having to write most of the boiler plate code.
http://www.mulesource.org/display/COMMUNITY/Home
Why would you go with anything other than the simplest thing that works?
In your case that sounds like EJB3 or maybe JMS, depending on whether the communication needs to be synchronous or asynchronous.
EJB3 is by far these easiest being built on top of RMI with the container providing all the additional features you might need - security, transactions, etc. Presumably your POJOs are in a shared jar and therefore can simply be passed between your EJBs, although I tend towards passing value objects myself. The other benefit of EJB is, when done right, that it's the most performant (that's just my opinion btw ;-).
JMS is a little more involved, but not much and a system based on asynchronous communication affords certain niceties in terms of parallelizing tasks, etc.
The performance overhead of web-services, the inevitable extra config and additional points of failure make them, IMHO, not worth the hassle unless you've a requirement that mandates their use - I'm thinking interop with non-Java clients or providing data to external parties here.
If you need network communication between Java-only applications, Java RMI is the way to go. It has the best integration, most transparency and the least overhead.
If, however, some of your clients aren't Java-based, you should probably consider other options (Java RMI actually have an IIOP-dialect, which allows it to interact with CORBA, however - I wouldn't recommend doing this, unless it's for some legacy-code integration). Depending on your needs, webservices are probably your friend. If you are conserned with the networkload, you could go webservices over Hessian.
You literally mean remotely? As in running in a different environment with therefore different availability characteristics? With network overheads?
Assuming "yes" my first step would be to take a service approach, set aside the invocation technology for a moment. Just consider the design and meaning of your services. You know they are comparativley expensive to invoke, hence small busy interfaces tend to be a bad thing. You know that the service system might fail between invocations, so you may favour stateless services. You may need to retry requests after failure, so you may favour idempotent service designs.
Then consider availability relationships. Can your client work without the remote system. In some cases you simply can't progress if the remote system isn't available (eg. can't enable the employee if you can't get to the HR system) in other cases you can adopt a "fire-and-tell-me-later" philosophy; queue up the requests and process responses later.
Where there is an availability depdency, then simply exposing a synchronous interface seems to fit. You can do that with SLSB EJBs, if everything is Java EE, that works. I tend to generalise expecting that if my services are useful then non Java EE clients may want them too. So SOAP (or REST) tends to be useful. These days adding a web service interface to your SLSB is pretty trivial.
But my pet theory is that any sufficiently large IT system ends up needing aynch communications: you need to decouple the availability contraints. So I would tend to look for a JMS-style relationship. An MDB facade in front of your services, or SOAP/JMS is not too hard to do. Such an approach tends to highlight the failure-case design issues that were probably lurking anyway, JMS tends to make you think: "suppose I don't get an answer? suppose my answer comes late?"
I would go for SOAP.
JMS would be more efficient but you would need to code up an message driven bean for each interface.
SOAP on the other hand comes with lots of useful toolkits that will generate your message definition (WSDL) and all the neccesary handlers (client and server) when given an EJB.
With soap you can (but dont have to) deal with certificate security and secure connections over public networks. As the default protocol is HTTP over port 80 you will have minimal pain with firewalls etc. SOAP is also great for hetrogenious clients (in your case anything that isn't J2EE) with good support for most common languages on most common platforms.

Categories