OSGI Apache felix- Hot deployment support - osgi

A little back ground: We are using Apache Felix implementation of OSGI for our web development (Adobe CQ5 which inturn is built on apache felix). We have a few bundles of our own (around 10) and each of them are configured as a project.
Issue: During the development lifecycle, we make changes to a bundle and then use an ant script to create the bundle and deploy it in the felix. I am wondering if there is some way to enable hot deployment of the changes I make during development mode that would save developers time.
Based on my research, we can use the felix file install which will monitor a folder(s) for changes to any bundles and can deploy them automatically. But this again means I need to run ant script to build the jar file and move it to the auto deploy folder the file install is watching. Is there a better/fast way to achieve this? The script is currently taking a around 10 seconds (approx) to compile the classes, create osgi specific meta data files, bundle the classes+metadata in a new jar. Is there some way to do hot deployment, so that any change I make to a java file is automatically reflected in the bundle?
Many thanks

If you develop your project in Bndtools, and run from the built-in launcher, then Bndtools will handle immediately building any Java code that you change, and deploying the updated bundle into the runtime. This leads to an extremely quick code/test/debug/fix cycle.
Having said that, I'm amazed that it takes 10 seconds to compile and build your bundles currently! Are you building on an extremely ancient computer? Or is the bundle multiple gigabytes in size?

We tried DCEVM and it does almost everything we expected to reduce the develop+fix+test life cycle. I recommend this to all java developers using big web applications. Thanks for your suggestion on bndtools Neil.

Related

Liferay portal deployment going into loop

We are using STS 3.4 to develop Spring portlets for Liferay 6.1.2. When we deploy the project onto the server by droping that on the server view, the deployment never gets completed.
It says the deployment is complete and portlets are ready to use but it again reinitiates the deployment process.
Any idea why this endless deployment loop is happening?
I'm not sure if STS is aware of Liferay's additional deployment process (or if you need/use it): Liferay typically processes a WAR file before actual deployment to tomcat, thus you should drop your WAR file to Liferay's deploy folder. This might add some libraries from Liferay itself (depending on your configuration in liferay-*.xml files or some other necessities that I don't remember.
Especially if you use Liferay's Plugins SDK (you don't state if you do or if you don't). If you indeed use it, you might want to try the Ant target direct-deploy for building the WAR file: The result of this should be able to deploy directly to tomcat. I'm assuming that STS omits the Liferay deployment process (and direct-deploy would mimic it). I hope (from memory) that it was available on 6.1 already.
Can't go without the hint that you should upgrade.

What is the recommended usage pattern for karaf-maven-plugin?

I have a bunch of java classes and a bundle activator class that I need to deploy to karaf.
I see that the karat-maven-plugin has kar packaging and karaf-assembly.
Also it generates features.xml
I can generate features.xml directly and it generates lines with wrap: for some of my dependent non-osgi jars.
But when I run karat-assembly, I run into the issue of the assembly goal not realizing that these jars are not osgi and end up with errors.
What it the recommended way to get a custom karaf with my application installed ?
Does the karat-assembly packaging need to have a features.xml generated and provided beforehand ? Or is it supposed to do the feature set generation by itself ? If it is the latter, then how do I get around the problem of the karat-assembly not recognizing non-osgi jars ?
I have spent a LOT of time with google and am stumped.
This is my procedure for creating a custom karaf distribution. It may not be "best practice" but it works for me. Maybe you can customize for your needs.
After developing my Camel routes and testing I generate my feature file based on a feature template found in /src/main/feature/feature.xml. The karaf-maven-plugin will generate the feature will in the feature folder inside /target.
I do a clean deploy to our maven artifactory.
I have a custom Karaf project do a clean install on that project. The project has dependencies to the initial project and I add all the features as boot level feature.
Once build I unzip the distribution and run the Karaf app. If everything looks ok its ready to be shipped.

OSGI vs Maven which is better packaging tool

We have a very big web application containing many features.Now for maintainability we want to split the application in components so that can remove / add particular components (jars). For that one suggestion is coming is to use OSGI. I think converting jars into bundle will take huge effort. I think same functionality can be achieved by Maven. According to my understanding OSGI is packaging tool. If I can make Maven plug-in for each component then any particular component can be included or removed at compile as opposed to run time as in case of OSGI.
Modularizing the application using Maven will be simpler than OSGI. I have read similar post on this site and it commented that OSGI and Maven are like comparing apple with orange. But I think in one sense both are same as they both meant for packaging difference is one is used at run time and one for compile time
Looking forward for well though answer :)
best wishes
Shailesh
As you already hinted at yourself: you're comparing apple with orange.
OSGi is not a packaging tool.
OSGi bundles are plain JAR files with some OSGi-specific metadata in the Manifest file.
You can create OSGi bundles using Maven e.g. using the Maven Bundle Plugin (I can recommend this approach). So regardless if you're using OSGi or not I strongly recommend using Maven.
Here some use cases for OSGi:
You want to create different versions of your application e.g. for different customers. With OSGi you can just add/ remove bundles without having to touch any other configuration.
You need a plugin system so 3rd parties can provide plugins to your application
You want your application to be truely modular
You want to share some code with other applications but want to hide some internal classes
...
OSGI is much much more than a packaging tool. You could say that OSGI has a packaging tool inside. Maven is a packaging tool and a dependency manager. I'd say that, given the level of complexity and the use you say you'll make of this technology, go with Maven.

Update dependencies while in hosted mode in GWT

I have a GWT webapp split into two Maven projects where one is a dependency to the other. Each time I change something in the dependency and I'm running webapp in hosted mode I have to rebuild the subproject and restart hosted mode for changes to apply. It takes a lot of time so I'd like to ask you if there is any way to make GWT using "live" version of the dependency?
There are 2 cases:
for server-side code, assuming you use the DevMode's embedded server, rebuilding the app and then refreshing the server should be enough
for client-side code, AFAICT, you have to use the source and output directories of the dependency module rather than the JAR containing them (GWT will load the source from the classpath, but apparently it'll only see the modified sources if it comes from a folder rather than a JAR; at least that's what I found in my tests). This goes against The Maven Way™ but the only solution so far is to use a special profile that will import the sources of the dependency project as sources of the project you're running. You can see examples of that in my archetypes.
There's actually a bug opened for the gwt-maven-plugin, MGWT-332, to do that automatically when running a reactor build. I also mused about what's really needed, for the forthcoming official gwt-maven-plugin (rewritten from scratch, independent from the CodeHaus Mojo plugin).
If your dependency does not come from a reactor build, then you're out on your own: you chose to make it totally distinct, so that's how it'll behave: you'll have to release it (even a snapshot) each time you make a change to it, and use the new version in your app (which means re-launching the DevMode).
This can be circumvented by running DevMode on your own, without the help of the gwt-maven-plugin. You're left on your own managing the classpath though (using the Google Plugin for Eclipse, I suppose you could simply edit the launch configuration to add the source folders of your dependency project to the classpath, before the classpath provided by Maven, that would reference the JAR).
Remove the dependent other application jar file from the primary application lib folder under webapp.
Eclipse should then resolve the dependency using the other project in the workspace if you have added it to your primary application classpath.
As GWT build takes ages, we invested some money in a JRebel license. We have two separate Eclipse projects for our back-end and our GWT front-end. JRebel reloads the classes automatically and I never need to restart my local server while writing code. It proved to be a wonderful time saver. Definitely worth the investment.

Maven cargo plugin - redeploy specific deployable in standalone container?

I'm currently working on a project that consists of several services written in Java that are accessed by a Ruby/Rails front-end. In an attempt to simplify local development, I've created a separate project that adds all of our service WAR projects as dependencies, and uses the cargo-maven-plugin to deploy each of these as a deployable inside of a single embedded Jetty instance.
The issue I'm having is that I'd like to be able to tell cargo to re-deploy a single WAR out of the several that are being run at a time. Starting the entire set of services from scratch takes a bit, and is really unnecessary when only one deployable has actually changed. As far as I can tell, the cargo:redeploy goal only works for non-standalone containers, and I also haven't been able to find any documentation that its possible to specify what you want to re-deploy on the command line.
Is there a way to tell cargo to re-deploy a single deployable from the command line? I'm thinking of something along the lines of mvn cargo:redeploy -DgroupId=com.foo.bar -DartifactId=baz
Apologies if this isn't clear, or if there is a different approach that I should be taking entirely - I'm relatively new to Java development and Maven.
Thanks for any help.
Download the latest war file to your local machine, then redeploy using the following pattern:
mvn install:install-file -DgroupId=com.foo.bar -DartifactId=baz -Dversion=1.x -Dpackaging=war -Dfile=C:/cargo.jar

Resources