I'm writing a Java API for several clients, and would internally like to use Spring and it's several features, but I don't want to expose to the client my dependencies.
Is this possible?
So if my client uses a different version of spring would they be insulated from my internal Spring dependencies.
If so, would my spring dependencies be bundled internally inside my jar? As well as would a custom class loader be required by my client application?
I have heard you can use this through OSGI bundles, but I'm wondering if this would satisfy my requirement.
The clients of my API wouldn't be OSGI enabled or we have no current environment that utilizes OSGI bundles.
It is not really feasible, or desirable to do so. Why would you want to "hide" the dependencies? Would you also want to hide a dependency on whatever logging package you may be using (for example)?
If you have the dependencies in your implementation, then they are best published as it will cause a lot less grief on the part of users of your API since they will know what conflicts may exist before they even attempt to use your code.
Don't forget, your users are actually developers and I am sure that they would rather be aware of any landmines or requirements up front.
Edit - Regarding OSGi:
OSGi will definitely take care of your conflicting dependencies issues, but it also would rely on deploying in an OSGi environment, which you haven't mentioned is the case for your clients. In addition, it is still not recommended to "hide" those dependencies in a bundle. The very nature of OSGi allows those conficting depencies to cooexist in the same application.
Related
I'd like to get CXF, which implements JAX-RS, up and running in OSGI (specifically, Apache Karaf running Apache Felix).
Using this project: cxf-osgi-activator as an example, I see that the engineer made a design decision to split up the jetty Karaf feature from the jax-rs Karaf feature. Is there a dependency between the two at runtime? Does the jax-rs feature use some trick (from the environment: OSGI HTTP Service, for example) to get itself listening for inbound connections, or is that still needed? Maybe my question can be answered with an explanation of line 250 of the RestDeployer.java file. Where is it pulling its Server from exactly? Does it always get one, or does it have a dependency on the jetty Karaf feature?
I had a look at the tests, which seem to use iPojo or Declarative Services (hard for me to tell the difference!) to cut down on boiler plate code, but at the expense of understanding (because it requires more in-depth knowledge on the subject than I have at the moment it would seem.)
The official CXF documentation is less than desirable on this subject.
My understanding is that it boils down to having:
a web resource file annotated with JAX-RS annotations to map inbound calls to local functions
CXF runtime (some registration service that manages the lifecycle from reception of a call to return of serialized information)
a server (Java Servlet or effectively an abstraction thereof that spawns threads for a given port) Purpose of cxf-rt-transports-http-jetty
How does this all play together in OSGI? I should also mention that am most familiar with Gradle, and the Maven pom.xml files likely contain things that I do not recognize.
I do not like the accepted answer to CXF web services with OSGI and Karaf, because it is specific to Blueprint, which I do not want to use because of its reliance on XML. I am looking for a technical answer here that explains the relationship between CXF and OSGI (like the OSGI HTTP Service).
Related:
Apache CXF/JAX-RS, Felix and Jetty
Purpose of cxf-rt-transports-http-jetty
Firstly, a tiny recap about OSGi :
OSGi is a specification that needs to be implemented
Felix/Equinox are the two implementations found in karaf (see your etc/config.properties, with the property karaf.framework to check the one you use, you can change it !)
Karaf is an administration tool that will use Felix/Equinox behind each command you make. Often, those commands are proxied to the corresponding behaviour defined by OSGi to the Felix/Equinox implementation.
So, the solution you linked with Blueprint is still true no matter your context. However, if you don't like Blueprint, you can either check Declarative Services where each "bean" you would have defined in a "spring/blueprint" world would become #Service/#Reference (more pure to OSGi original way of thinking) or use OSGI CDI Integration which will be way more intuitive if you are used to the more classic #Named/#Inject way of thinking inside a bundle.
But in the end, it's exactly the same principles : you want to have a Server running registering itself to the CXF Bus (which normally you shouldn't declare in your bundle, you can use the default one) and your Service registering itself in Server.
I'm currently working on an ebanking platform, so out customers are banks. To extend this platform, we develop our own 'xDK' (development kit) for 3rd party developers (usually the banks themselves).
When xDK is used as a dependency (via maven or gradle), it brings along a lot of transitive dependencies in order to work (~25MB). I was trying to think of solutions to make the dependency a bit lighter to use (given that it needs all of its dependencies) which in turn will promote having smaller, more focused services (not exactly micro-services but at least a step closer).
The current situation's benefit is that every service/project can use its own version of xDK and it doesn't have to update until it needs to. The problem is that it doesn't scale. If we assume 100 WAR files having xDK as a dependency, we create a 2.5GB overhead on the application server (even if they all use the same version).
I'll list two options I was thinking of, but I'd like to know if there are better solutions for this problem. Feel free to ask for more info. Thanks in advance.
Similar to JavaEE components (JPA, JAX-RS, ...), we'll have an 'api' dependency and the implementation. The projects will only declare the 'api' as a provided dependency while the implementation will be provided like so:
JBoss module
I haven't worked with other application servers. We (and our customers) only use JBoss EAP, so this might be a JBoss specific solution. We can create a JBoss module for xDK and then make every deployment depend on it via the JBoss deployment descriptor. The benefit is that we get rid of the multiple copies of the library, but we lose on version flexibility. This would mean that there needs to be some kind of governance on which version of xDK you code against in your service. Also, every time there is a breaking change, we'd need to update all services if we want to update the JBoss module to the latest version.
Bundle in an EAR
EARs allow multiple WAR files in them and also jars as libs. xDK will be an EAR dependency. Again, we have the same pros and cons as the previous solution. This solution is JBoss independent. However, it needs an extra build step to collect all the projects and bundle them, which might be annoying for out customers if they need to bundle their own services.
How about using the maven dependency scope of provided to declare that for the individual war files the jar file is provided outside of the war file, and then have another mechanism to inject the shared jar file into the application server?
c.f. https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
When I first started looking at OSGi I was under the impression that you could just build a JAR and as-long as it had a manifest file, you could deploy it in a OSGi container. I imagined building my modules in a classic way (maven), and maybe use some plugin or something of the sort to write the manifest, I could then have my module that would basically be a standalone application communicating with other modules through OSGi.
Further reading about OSGi, I'm beginning to see more examples of it being used at a more low-level and basically replacing dependency injection and providing cross-cutting concern services like logging. And seems that using things like hibernate or others, is a problem... (or maybe I'm just missing something).
At least for me, I don't really see the point of having a such fine-gained level of modularity and integration to OSGi, I would much rather have a separate modules, each one of them having its own set of technologies and frameworks, and possibly a web resources and persistence layer. Is this achievable with OSGi? If yes, can you point me in the right direction, examples etc.?
edit, added some more details of how I'm trying to use OSGi:
I'm just envisioning the possibility of having a more than one-class module, that might have a more higher-level responsibility.
Like say agenda module. In this case I want to have things like, persistence of the events, add events, list events with filters, etc...
This agenda might have several internal classes, and might even need a persistence layer. So I would like to use something like Guice to DI those classes, and some JPA to persist my data.
I can understand that some X-cutting concerns like server or logging can have a bundle, but the data model is specific to the agenda bundle. So I think my question was at the end What is and what is not possible to do inside a bundle? And what should and shouldn't be done inside as a general practice?
Thanks!
Mauricio
You can use OSGi without forcing any dependencies on OSGi on the application code. However, since OSGi provides modularity, the middleware (your layers) need to have some knowledge of OSGi. The problem is that in a modular world you want to hide implementation details, that is the whole purpose. However, things like Spring and Hibernate tend to assume the classpath has no boundaries and they run head on into the fences. Fortunately, more and more middleware is becoming prepared for this, I heard Hibernate now has an effort and JPA is also available in OSGi.
OSGi is many things to many people, and you can almost pick and choose what parts of it you want to use:
Do you have a plain library that doesn't use any other dependencies? Sweet, just put up a minimal MANIFEST.MF listing the public packages, use maven to build your JAR and you're done.
Do you have dependencies? Same as (1), you just add the imported packages in your manifest.
Do you need to perform some initialization? Write an Activator, and mention it in your manifest.
Services? Just put the dependencies and descriptions of those in XML files and add them in the manifest.
And so on - just use the level where you are comfortable.
On the other hand, if you want to do web applications you really need to consider the architectural interplay between OSGi, the libraries you use, your application manager and the servlet/jee/whatever container. At what level will OSGi reside? In a general sense, there are OSGi->container->app, container->OSGi->app and container->app->OSGi solutions, and each has their own idiosyncrasies.
Concerning building with maven, you can use the Maven-Bundle-Plugin it helps you to build OSGi bundles without having to write the manifest on your own. All the required meta information will be in your POM.
Dependency injection can be achieved on top of the module layer. One possible solution would be Declarative Services which enables you to inject via an XML description or code annotations. It strongly reflects the dynamic nature of OSGi Services (dynamic binding unbinding of services).
The alternative is Blueprint which is based upon spring and features a very similar syntax. One key feature is that it can abstract the nature of binding and unbinding of services. If you think about using Spring, use Blueprint.
OSGi only implies how you structure your modules. You get a well defined graph of module interactions (who imports/exports a package? Who exports Services and who uses it?)
therefore you can build an enterprise architecture on top of it by building cohesive bundles for every task.
OSGi is sometimes referred to as a service-oriented architecture for the JVM. Looking at bundles as modular units that provide services helps define the right granularity: you'll usually have API bundles which are just here to provide java packages that define APIs, service bundles that provide implementations of these APIs, and utility/auxiliary bundles that provide the cross-cutting services that you mention.
You can use some dependency injection frameworks on top of OSGi, but from my experience (with Apache Sling and Adobe CQ5) keeping things simple is often better. The OSGi Service Component Runtime and Configuration Admin provide all I need to manage services, dependencies and configurations, especially if you design your system for that from the beginning.
You can find a bit more about our experience with OSGi in designing Adobe CQ5 in my "tales from the OSGi trenches" slides at http://www.slideshare.net/bdelacretaz/tales-from-the-osgi-trenches-2012-short-form-edition - that might help get a better feel for how OSGi is used in building complex systems.
Being someone who is allergic to dependencies, when would I use something like OSGi instead of the built in java 6 http://java.sun.com/javase/6/docs/api/java/util/ServiceLoader.html (I want to let plugin jars just be dropped in).
(FYI this is in a scala app, open to any suggestions, ServiceLoader is pretty damn close to what I want).
If ServiceLoader mostly fits your needs, that says that you're looking for service discovery via the presence of files on the class path. That's only a small part of what OSGi provides.
OSGi will let you dynamically install bundles, advertise services, revoke advertisements, and uninstall bundles all while the application is running. Furthermore, as a consumer of services, you can look them up eagerly -- with filtering predicate queries -- and detect when offered service providers come and go. These bundles need not lie on the class path, and they can be provided in various forms; Jar files and "exploded directories" are the two I recall.
By contrast, ServiceLoader does just one thing: it exposes discoverable factories. Usually you'll create a factory-style interface that takes some argument to decide whether that provider can offer the appropriate service, such as mapping a given character set name to a CharsetDecoder. There's no formalized protocol for acquiring and releasing a service from such a provider. OSGi does formalize the binding and unbinding of consumers to services. The consumer can receive notification when new providers come online, and the provider can receive notification when a consumer acquires and releases a service instance. If this life-cycle control is important to your service and you forgo OSGi, you'll have to build this yourself; ServiceLoader doesn't go that far.
Alternately, rather than eager service lookup and use, you can take a more passive, declarative approach and let one of the OSGi dependency managers match your stated needs to the available service providers. There are many dependency managers to choose from. Spring Dynamic Modules is one of the most capable.
OSGi provides many other "middleware" facilities. I won't try to sell you on them here, as your question focuses mostly on what you'd be missing out on by choosing ServiceLoader.
As seh points out, if you're only interested in simple service discovery then ServiceLoader is a lightweight way to decouple consumers from providers. But it doesn't offer any assistance with composing services together.
For example, suppose service A needs to use service B. This is a "service dependency"... but what should A do if B is not available? In OSGi we can arrange that if B is not available then neither will A be -- assuming the dependency is mandatory; we can also support optional dependencies. On the other hand when using ServiceLoader, service A has no control over its availability so long as the JAR enclosing it is on the classpath... so it must provide its functionality even in the absence of required "back end" services.
Another thing to bear in mind with ServiceLoader is to try to abstract the lookup mechanism. The publish mechanism is quite nice and clean and declarative. But the lookup (via java.util.ServiceLoader) is as ugly as hell, implemented as a classpath scanner that breaks horribly if you put the code into any environment (such as OSGi or Java EE) that does not have global visibility. If your code gets tangled up with that then you'll have a hard time running it on OSGi later. Better to write an abstraction that you can replace when the time comes.
In Java, I can dynamically add stuff to classpath and load classes ("dynamically" meaning without restarting my application). Is there a known framework/library which deals with dynamic loading/unloading of modules without restart?
The usual setup, especially for web-apps, is load balancer, several instances of application, and gradual deployment and restart of new version. I'm looking for something else - application with several services/plugins, possibly single-instance desktop application, where disabling single service is cheap, but bringing down or restarting complete application is not feasible.
I'm thinking about typical plugin infrastructure, where plugins can be upgraded or installed without restarting application. Do I have to program that from scratch, or is something already available? Spring-compatible and opensource is a plus, but not a requirement.
You might consider running your spring application in an OSGI framework.
I believe the DMServer is a module-based Java application server that is designed to run enterprise Java applications and Spring-powered applications, based on OSGI
You can find more details in this Hello, OSGi, Part 2: Introduction to Spring Dynamic Modules article, in particular how to use Spring DM to dynamically install, update, and uninstall modules in a running system.
Note: when you speak about "plugins can be upgraded or installed without restarting application", OSGI is the first candidate framework that comes to mind.
It is all about modularization of applications into smaller bundles.
Each bundle is a tightly-coupled, dynamically loadable collection of classes, jars, and configuration files that explicitly declare their external dependencies (if any).
Perhaps the simplest approach is to load each plugin with it's own class loader. Then discard the class loader and create a new one to reload the plugin. You will want init() and destroy() methods in the plugin API to allow a chance for startup/shutdown type functionality.
This also has the advantage of isolating the plugins from each other.
A URLClassLoader is your starting point for this. The general idea is that you provide a XxxPlugin superclass that any plugin subclasses. Consider the example of Applet, which is essentially a GUI plugin (or Midlet, etc).