answers inline

On 07.09.20 13:48, Manuel Souto Pico wrote:
[...]
My Groovy script runs within a Java application (called OmegaT). This
application extends its functionality by loading the jar files it finds
in the /plugins folder of the installation. Even though they are
optional and added/removed on demand, once the application runs, the jar
files are loaded and become part of the running code that is being
executed just as the code base of the application itself. My script
downloads those jar files for the user and puts them in the /plugins
folder.

ok, that makes much more sense to me now. But it sounds like a problem
with class loaders... to illustrate it:

m = new Map()
m[X.class] = 1

then the class X, loaded through a class loader clx (example), can only
be unloaded if neither X, nor clx are still referenced. But as long as
the map m above exists, this is not the case and they stay in memory.

in extension that means if X comes from X.jar, the class loader clx
keeps the file X.jar open, till clx (and X) can be garbage collected

However, as there are updates in the jar files (and new versions
normally have a different name), my script needs not only to download
(and overwrite) the new ones but also delete the old ones. That's
because, even though I'd think it should be easy for the application to
sort what it finds and pick the one with the latest version number, in
practice it seems that's not so easy -- the developers say the loading
order is not guaranteed (it's up to the classpath loader to determine
which one is used). To avoid that the application uses an old jar file
instead of the new one, they should be deleted (i.e. my script's job).

sounds like the simple variant to load plugins. Not that this is wrong,
it just does normally not support unloading plugins properly. And
without that your usage scenario cannot work.

Now, why are they (normally) locked? I guess it is because the
application loads them and opens them all when it is launched.

they are two simple variants. One is they are loaded together with all
the other code of the application, like you said. the other is that
there is a specific loader for the plugins, that is employed later for
this.

There are other solutions, but I doubt they are involved. Only in the
second case you could have a chance, but it is unlikely

So, even
though one version only is used in the end (if the application can see
that they are different versions of the same plugin and picks only one),
it seems all the jar files in the folder are (normally) loaded and
locked. Which is, I think, what you mean in your last paragraph.

that works like this...

def x = new X()

this means to create an instance of X we first need to load the class X.
To do this the current class loader (every class/script has one) is
asked for the class X.

A standard classpath class loader now goes through the jars, till it
finds the class X. Now there is a fixed relation between the class X,
that class loader and that specific jar. If there are other jars, that
also have X, they are ignored. So if you have X-1.jar and X-2.jar it
depends on the order of the lookup in the jars if X is taken from
X-1.jar or X-2.jar.

If the libraries have the same set of classes it is only a question of
what version is used. But things can be a lot worse.

And your conclusion might be, unfortunately, correct. I had a hope that
someone here could suggest a creative alternative. Either that, or the
dirty hack I mentioned.

a switch to OSGI could solve the problem, but that is quite the change
already. Without that the application would have to explicitly support
this scenario and that is more or less difficult. It really depends on
the application and requires a much more in detail look at the
application to find out if that is even possible.

Is the purpose of all this really to update jars while the application
is running? Or do you need only to change something from the jars?

bye Jochen

Reply via email to