Since the introduction of JLink
(maybe a bit later) it is possible to put jar libraries inside the directory-structure of packages. If this package is installed in one of the places Mathematica searches, the jar libraries are automatically found by JLink
.
The problem is that under 64 bit Windows XP, after loading JLink
these files are locked and cannot be removed from within Mathematica, although none of the jars are really used, but only added to the class-path of Java.
Let me give a short example: Place a Test
folder with Java
subfolder inside your $UserAddOnsDirectory
and copy any jar file into the Java
folder. This looks like
Test/
└── Java
└── blub.jar
When you now start a fresh Kernel and load <<JLink`
you can verify by looking at JavaClassPath[]
, that this directory and the jar was indeed added to the class-path. When you try to remove the complete folder, you get (a misleading) error message
DeleteDirectory[path, DeleteContents -> True]
(*
DeleteDirectory::dirne: Directory D:\Documents and Settings\mscheibe\
Application Data\Mathematica\Applications\Test not empty. >>
*)
After Quit
-ing the kernel, calling UninstallJava[]
or JLink`QuitJava[]
the directory can be removed. This behavior does not occur in Linux or on MacOSX and I could only test it on Windows XP 64 bit
.
Question: Why, if the jar-path is only appended to the class-path, does JLink
lock the files as they where opened for reading? Why does this happen on Windows
only? Is there anyone, who has a deeper insight into JLink
who can suggest a better solution that calling JLink`QuitJava[]; Pause[2];
inside my module when I want to remove a jar-file found by Mathematica.
Remark 1: This behavior is not restricted to automatically found jars. When you use java-code by manually adding a jar with AddToClassPath[path]
the similar thing happens.
Remark 2: I forgot to mention, that JLink`QuitJava[]
does not really quit java like Quit
would kill the kernel. Meaning, I call this and without doing anything else I can still call my functions inside the jars. This seems to suggest, that QuitJava[]
kills the class-loader instance Leonid is mentioning which locks the files. But a call to e.g. JavaNew
seems to set up everything correct again.