4

I'm writing a server application which makes use of external modules. I would like to make them to be upgradeable without requiring server restart. How do I do that? I've found OSGi but it looks very complicated and big for my task.

Simple *.jar files are ok, but once they are loaded, I suppose, I cannot unload them from VM and replace with another version on-the-fly.

What approach can you suggest?

Vladislav Rastrusny
  • 29,378
  • 23
  • 95
  • 156

5 Answers5

4

It seems like OSGi is exactly what you're asking for. It can be complex, but there are ways to deal with that. Some of the complexity can be mitigated by using SpringDM or something similar to handle the boilerplate tasks of registering and consuming services in the runtime. Annotation-driven service registration and dependency injection really reduces the amount of code that needs to be written.

Another way to reduce complexity is to deploy the bulk of your application in a single bundle and only deploy the parts that need to be modular into their own bundles. This reduces your exposure to registering and using services from other bundles in the runtime as well as reducing the complexity of deployment. Code running within a bundle can use other code in the same bundle just as in a standard Java app - no need to interact with the OSGi runtime. The opposite of this approach is to break up your application into lots of discrete bundles that export well-defined services to other bundles in the system. While this is a very modular approach, it does come with extra complexity of managing all those bundles and more interaction with the OSGi runtime.

I would suggest taking a look at the book "OSGi in Action" to get a sense of the issues and to see some decent samples.

Michael Pigg
  • 596
  • 3
  • 5
  • The problem is that it's too complicated it seems. What I want is some easy way like LoadLibrary/FreeLibrary in Windows. Not literally of course ;) – Vladislav Rastrusny Apr 06 '11 at 18:00
2

It would at least require you to define your custom classloader... I don't see how can this be simpler than just using Felix, Equinox, Knoplerfish or any open source Osgi runtime to do the task. Maybe SpringDM is simpler...

Riccardo Cossu
  • 2,699
  • 1
  • 28
  • 47
  • Is there any helloworld at least for one of them? I don't need anything serious, just loadable/unloadable classes or packages. – Vladislav Rastrusny Mar 31 '11 at 09:54
  • Felix's site is full of tutorials; really, class loading/unloading is not a simple matter, I think there could be no "HelloWorld" scenario. Osgi is IMHO the simplest way to achieve what you seek. My 2c anyway :-) – Riccardo Cossu Mar 31 '11 at 12:16
1

What you're going for is definitely possible. I believe that you can unload classes from memory by loading them in a separate ClassLoader and then disposing that ClassLoader. If you're not wanting to go all out and use OSGI, I'd recommend something like JBoss Microcontainer (http://www.jboss.org/jbossmc) or ClassWorlds (http://classworlds.codehaus.org/). It's not too terribly difficult to write something like this from scratch if your needs are specialized enough.

Hope this helps, Nate

NateTheGreat
  • 2,295
  • 13
  • 9
1

If you follow the ClassLoader route (is not that difficult, really), I suggest each module to be packaged in its own jar, and use a different ClassLoader to read each jar. that way, unloading a module is the same as "discarding" the ClassLoader.

Soronthar
  • 1,601
  • 10
  • 10
  • And what happens if you discard a class loader, having an instance of that class still referenced somewhere in code? Or worse, what if you load a class with the same name but of another version while there are still references to old instances? Will it throw exception or something? – Vladislav Rastrusny Mar 31 '11 at 09:56
  • It depends. Even is the ClassLoader is discarded, the Class will not be "unloaded", in the sense that it will not be GC, until all instances of that class are GC first. But all attempts to create a new instance will be received with an Exception. – Soronthar Mar 31 '11 at 18:24
0

OSGi is not so complicated - using PAX runner with maven worked as a breeze.

Or implement your own ClassLoader and set it to JVM : java -Djava.system.class.loader=com.test.YourClassLoader App.class

Rostislav Matl
  • 4,294
  • 4
  • 29
  • 53
  • Can you suggest some helloworld-like examples on OSGi use for solving problem like mine? Also, are classloaders allowed to UNLOAD classes? And can they be chained so that my classloader loads only modules leaving the rest to the default one? – Vladislav Rastrusny Mar 30 '11 at 13:44
  • Hmm, I looked on web and for the OSGi part look at http://www.baptiste-wicht.com/2010/07/osgi-hello-world-services/ , for the PAX part look here : http://www.sonatype.com/people/2009/09/maven-tips-and-tricks-creating-an-osgi-project-with-maven/ . AFAIK ClassLoaders will not help you witn unloading. – Rostislav Matl Mar 30 '11 at 14:08
  • What about "discarding" ClassLoaders as @Soronthar suggested? Will it really unload a class? – Vladislav Rastrusny Mar 30 '11 at 17:10
  • It should, but AFAIK this discarding is done by garbage collector, so it's unpredictable and quite complicated. – Rostislav Matl Mar 31 '11 at 08:06
  • @binary_runner I think he spoke of http://download.oracle.com/javase/1.4.2/docs/api/java/lang/ClassLoader.html#clearAssertionStatus() clearAssertionStatus() method of ClassLoader, not about garbage collector. Can this be? – Vladislav Rastrusny Mar 31 '11 at 08:16
  • I don't knwo this API. From documentation I'd guess it serves different purpose. – Rostislav Matl Apr 06 '11 at 08:51