Thanks, Jochen.

I'll share this thread (and your comments) with the Java developers that
work on OmegaT (the application).

To answer your question: the purpose is to update the jar files (if there
is an update available) before the user actually works on the application.

So the sequence is:
1) the user launches the application,
2) the script runs on startup (before the user can do anything else) and
checks whether there's an update
-- 2.1) if there is one it tries to download it and update the plugins
3) after updating the plugins (downloading the new, deleting the old), the
application shuts down, so that it can pick and use the new version of the
plugins when it restarts

The update wouldn't really need to happen while the application is running,
but since the script runs within the application and only the application
knows where the plugins folder is, that's what happens.

So the idea is to substitute the file (delete old version, put new version
-- and overwritten the new version, in case the remote plugin has been
updated but it's name hasn't changed).

I guess in theory the script could also edit/update the content of the
locale jar file and then rename the file... ? (so the deleting problem does
not exist.. ) but I don't know how feasible that is tbh.

Thanks.

Cheers, Manuel

Jochen Theodorou <blackd...@gmx.org> escreveu no dia segunda, 7/09/2020
à(s) 18:16:

> 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