Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid file leak in JavaSPIExtensionLoader #637

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

WolfgangHG
Copy link
Contributor

This is the same that was already done for RemoteExtensionLoader in #502: when running the test suite for https://github.com/arquillian/arquillian-extension-warp with the Glassfish profile (Glassfish 7.0.18), on windows there are file leaks that cause every test to take 20 seconds. Reason: Glassfish cannnot delete "arquillian-core.jar" on undeploy.

Using File Leak Detector, I found that org.jboss.arquillian.container.test.impl.RemoteExtensionLoader is the culprit for this leak: URL.openStream creates a java.net.JarConnection that caches opened files by default.
As those files are accessed only once in Arquillian, there is no performance reason to cache them.

This pull request switches off caching.

WildFly is not affected by this problem because of the underlying VFS implementation. But GlassFish accesses the files directly.

For the archive: this is the stack trace that "File Leak Detector" reports:

  #43 C:\Temp\glassfish7\glassfish\domains\domain1\applications\test\WEB-INF\lib\arquillian-core.jar by thread:admin-listener(3) on Sat Oct 26 16:06:49 CEST 2024
        at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:187)
        at java.base/java.util.jar.JarFile.<init>(JarFile.java:348)
        at java.base/sun.net.www.protocol.jar.URLJarFile.<init>(URLJarFile.java:103)
        at java.base/sun.net.www.protocol.jar.URLJarFile.getJarFile(URLJarFile.java:72)
        at java.base/sun.net.www.protocol.jar.JarFileFactory.getOrCreate(JarFileFactory.java:106)
        at java.base/sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:132)
        at java.base/sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:175)
        at java.base/java.net.URL.openStream(URL.java:1165)
        at org.jboss.arquillian.core.impl.loadable.JavaSPIExtensionLoader.load(JavaSPIExtensionLoader.java:169)
        at org.jboss.arquillian.core.impl.loadable.JavaSPIExtensionLoader.all(JavaSPIExtensionLoader.java:74)
        at org.jboss.arquillian.core.impl.loadable.LoadableExtensionLoader.locateExtensionLoader(LoadableExtensionLoader.java:116)
        at org.jboss.arquillian.core.impl.loadable.LoadableExtensionLoader.load(LoadableExtensionLoader.java:65)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:86)
        at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:103)
        at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:90)
        at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:134)
        at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:106)
        at org.jboss.arquillian.core.impl.ManagerImpl.fireProcessing(ManagerImpl.java:298)
        at org.jboss.arquillian.core.impl.ManagerImpl.<init>(ManagerImpl.java:93)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at org.jboss.arquillian.core.spi.SecurityActions.newInstance(SecurityActions.java:144)
        at org.jboss.arquillian.core.spi.SecurityActions.newInstance(SecurityActions.java:89)
        at org.jboss.arquillian.core.spi.ManagerBuilder.create(ManagerBuilder.java:68)
        at org.jboss.arquillian.warp.impl.server.execution.WarpFilter.init(WarpFilter.java:69)
        at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:227)
        at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:83)
        at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3896)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4503)
        at com.sun.enterprise.web.WebModule.start(WebModule.java:547)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:935)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:917)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:653)
        at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1795)
        at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1483)
        at com.sun.enterprise.web.WebApplication.start(WebApplication.java:88)
        at org.glassfish.internal.data.EngineRef.start(EngineRef.java:97)
        at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:278)
        at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:344)
        at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:533)
        at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:257)
        at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:471)
        at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:574)
        at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:570)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
        at java.base/javax.security.auth.Subject.doAs(Subject.java:361)
        at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:569)
        at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:600)
        at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:592)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
        at java.base/javax.security.auth.Subject.doAs(Subject.java:361)
        at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:591)
        at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1484)
        at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1862)
        at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1738)
        at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:233)
        at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:213)
        at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:253)
        at org.glassfish.admin.rest.resources.TemplateListOfResource.createResource(TemplateListOfResource.java:305)
        at org.glassfish.admin.rest.resources.TemplateListOfResource.post(TemplateListOfResource.java:142)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:146)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:189)
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:93)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:478)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:400)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
        at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:274)
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:266)
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:253)
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:696)
        at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:367)
        at org.glassfish.admin.rest.adapter.RestAdapter$2.service(RestAdapter.java:291)
        at org.glassfish.admin.rest.adapter.RestAdapter.service(RestAdapter|#]


In case someone wants to reproduce it: you first need my pull request for Weld (weld/core#3069) where something similar happened. After replacing the fixed Weld version, the issue from this pull request is reported.

And if both fixes are applied, the jars are no longer locked an can be deleted on undeploy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants