Jump to content
Excelsior Forums
Sign in to follow this  
David

Complying with LGPL - runtime loading of classes

Recommended Posts

We are using the Hibernate ORM library in our project (plus the various libraries that Hibernate requires of course). Hibernate is published under the LGPL2.1.  Now, the LGPL allows us to link to the Hibernate libraries, BUT it also requires that the end-user be able to REPLACE the library (maintaining interface compatibility) should they so wish.

What this means is that if a user had a copy of our aplication, and wanted to run it using a patched version of Hibernate that he had built, he must be able to do so.  (There is some discussion around this on this thread: https://opensource.stackexchange.com/questions/4624/dynamic-linking-lgpl-library-and-licensing-in-windows-store-app/4625#4625)

Up to now, I had been assuming we would build our application + libraries into a single EXE. But that means replacing a library would be impossible (all the libraries are "baked in" to the EXE). So we need a mechanism for allowing replacement of classes once an application has been built.

There are 2 ways we could comply with the LGPL here -

1) Provide our application as an "object file" - ie., the compiled output from Jet. We separate our project into "our application", and "libraries", and compile them separately as a multi-component application.  The problem here is that the end-user would be unable to re-link, since they would need their own copy of Excelsior Jet to compile their patched version of Hibernate. OK, so the user can technically get a free-for-personal use version of Jet now, but I don't think that complies. The key bit of the license text is this:  "... must include any data AND UTILITY PROGRAMS needed for reproducing the executable" (emphasis mine).   To properly comply with the LGPL we would have to be able to redistribute Excelsior compiler and linker binaries ourselves (on demand from a user).  So that's not really an option.  Unless Excelsior want to be totally awesome and release a stripped-down command-line-only set of tools that can be re-distributed for this purpose. That would be immensely cool.

or:

2) Load the Hibernate libraries dynamically at run-time from a plain JAR file, using the mixed compilation model. Performance would obviously not be as good, but I assume that would work OK. We may possibly be able to provide 2 builds - a normal build where the libraries are statically linked into a single exe, and an alternate build where we put library JAR files in a subdirectory under the main application and load then dynamically at application startup, allowing users to simply "drop in" a replacement library jar file should they so wish.

 

Are there any other options I could consider?

 

An "ideal" solution for building applications using LGPL libraries would actually be something like a very minimal compiler tool for Jet that could compile a Jar file and produce a standalone "object module" that could be loaded by a Jet-compiled application at run-time. The tool would need to be freely redistributable, but would only need to do the basic job of converting a jar file into a compiled module. The main application (built by the full Jet application) would load and dynamically link to those modules at startup (e.g., like a DLL).

Share this post


Link to post
Share on other sites

Actually, you can exclude LGPL jars from the project and compile them into a separate DLL. Make sure it's not explicitly imported in the main project via the !uses directive.

After that, use run-time linking as described in https://www.excelsiorjet.com/docs/jet/jetw012#0383

As a result, you ship optimized code in a DLL. If and when an end user wishes to replace it with jars, s/he can do that and the jars will be loaded by JIT (with performance loss, though).

 

 

Share this post


Link to post
Share on other sites

Hi  -- thanks for the comment, but I'm confused as to how Jet would know to load a jar file that overrode class definitions provided in compiled code (even if it was dynamically linked).  I can see how to set up a jar file classpath entry, but if I have the same class defined in two places (a jar file and a DLL) what would the Jet runtime do? I guess I could explicitly load the jar and the initial Hibernate configuration classes via a URL Classloader (if the jar was present), but would that cause all related classes to be also loaded from that jar?  Or would the compiled classes take precedence (which is what I would expect from default Java classloader behaviour, to be honest)?

I can't see anything in the documentation about this. Guess I need to do some experimenting...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×