简体   繁体   English

从JNI卸载JAR文件

[英]Unload JAR file from JNI

I have a problem with the Java Native Interface. 我的Java本机接口有问题。

I use the JNI in my application, everything is working fine except the fact that I'm unable to unload / release the lock from the .JAR file im accessing with the JNI. 我在应用程序中使用了JNI,除了我无法从JNI访问的.JAR文件中卸载/释放锁这一事实之外,其他一切都工作正常。

Here is the destructor I'm using: 这是我正在使用的析构函数:

destructor Schnittstelle.Destroy;
begin
try
if (assigned(FJNIEnv)) then
begin
  ShowMessage('Destruktor');

  FJNIEnv.Free;
  FJNIEnv := nil;

  FJavaVM.JavaVM^.DetachCurrentThread(FJavaVM.JavaVM);
  FJavaVM.JavaVM^.DestroyJavaVM(FJavaVM.JavaVM);

  FJavaVM.Free;
  FJavaVM := nil;

  inherited Destroy;
end;
except
  ShowMessage('Java VM kann nicht freigegeben werden.');
  Exit;
end;
end;

After the desctructor is called, I try to change the JARs file name to test if the JNI stopped accessing the file, but thats not the case. 调用desctructor之后,我尝试更改JAR文件名以测试JNI是否停止访问该文件,但事实并非如此。

If I terminate my delphi application the JAR file is usable. 如果我终止我的delphi应用程序,则JAR文件可用。

Thank you! 谢谢!

You not specify in your question how you load the classes in the JAR file, directly via JNI o indirectly thru some Java call. 您没有在问题中指定如何直接通过JNI或通过某些Java调用直接在JAR文件中加载类。

Anyway I make the assumption that class loading inside the JVM, either with Class.forName(String) or ClassLoader.loadClass(String) uses the same mechanisms as the JNI FindClass : 无论如何,我都假设通过Class.forName(String)ClassLoader.loadClass(String)在JVM内部ClassLoader.loadClass(String)使用与JNI FindClass相同的机制:

FindClass 查找类

In JDK release 1.1, this function loads a locally-defined class. 在JDK版本1.1中,此函数加载本地定义的类。 It searches the directories and zip files specified by the CLASSPATH environment variable for the class with the specified name. 它在CLASSPATH环境变量指定的目录和zip文件中搜索具有指定名称的类。

Since Java 2 SDK release 1.2, the Java security model allows non-system classes to load and call native methods. 从Java 2 SDK 1.2版开始,Java安全模型允许非系统类加载和调用本机方法。 FindClass locates the class loader associated with the current native method; FindClass查找与当前本机方法关联的类加载器; that is, the class loader of the class that declared the native method. 也就是说,声明了本机方法的类的类加载器。 If the native method belongs to a system class, no class loader will be involved. 如果本机方法属于系统类,则不涉及任何类加载器。 Otherwise, the proper class loader will be invoked to load and link the named class. 否则,将调用适当的类加载器以加载和链接命名的类。

Since Java 2 SDK release 1.2, when FindClass is called through the Invocation Interface , there is no current native method or its associated class loader. 从Java 2 SDK 1.2版开始, 通过Invocation Interface调用FindClass时 ,没有当前的本机方法或其关联的类加载器。 In that case, the result of ClassLoader.getSystemClassLoader is used. 在这种情况下,将使用ClassLoader.getSystemClassLoader的结果 This is the class loader the virtual machine creates for applications , and is able to locate classes listed in the java.class.path property. 这是虚拟机为应用程序创建的类加载器 ,并且能够找到java.class.path属性中列出的类。

Also see this other considerations over unloading of the JVM : 另请参阅有关卸载JVM的其他注意事项:

It seems that the JVM is not completely unloaded until the program exits. 看来直到程序退出,JVM才完全卸载。

I guess that the system classloader that is referencing the jar file and the classes in it is not closed until the JVM is unloaded, so I guess that it is not possible to unload the jar until the program exits. 我猜想引用该jar文件及其中的类的系统类加载器要等到JVM卸载后才能关闭, 因此我想在程序退出之前无法卸载jar。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM