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

Payara 457 classloader work #467

Merged
merged 7 commits into from
Oct 8, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2015] [C2B2 Consulting Limited]
package com.sun.ejb.containers;

import com.sun.enterprise.deployment.xml.RuntimeTagNames;
Expand Down Expand Up @@ -100,6 +101,9 @@ protected void afterExecute(Runnable r, Throwable t) {
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// clear our Context Classloader
Thread.currentThread().setContextClassLoader(null);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2015] [C2B2 Consulting Limited]

package org.glassfish.ejb.startup;

Expand Down Expand Up @@ -70,6 +71,8 @@
import org.jvnet.hk2.annotations.Service;
import org.glassfish.hk2.api.PerLookup;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.pfl.dynamic.codegen.impl.CurrentClassLoader;
import org.glassfish.pfl.dynamic.codegen.spi.Wrapper;

/**
* This class represents a logical collection of EJB components contained in one ejb-jar
Expand Down Expand Up @@ -232,6 +235,11 @@ boolean loadContainers(ApplicationContext startupContext) {
} catch(Throwable t) {
abortInitializationAfterException();
throw new RuntimeException("EJB Container initialization error", t);
} finally {
// clean up the thread local current classloader after codegen to ensure it isn't
// referencing the deployed application
CurrentClassLoader.set(this.getClass().getClassLoader());
Wrapper._clear();
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
import org.glassfish.hk2.api.ServiceLocator;

import javax.inject.Singleton;
import org.glassfish.api.invocation.InvocationManager;
import org.jvnet.hk2.config.types.Property;

//import com.sun.messaging.jmq.util.service.PortMapperClientHandler;
Expand Down Expand Up @@ -336,6 +337,9 @@ private static enum ClusterMode {

@Inject
private ApplicationRegistry appRegistry;

@Inject
InvocationManager invManager;

/**
* Constructor for an active Jms Adapter.
Expand Down Expand Up @@ -539,6 +543,8 @@ public Object run() throws
//set the JMSRA system property to enable XA JOINS
//disabling this due to issue - 8727
//System.setProperty(XA_JOIN_ALLOWED, "true");

// to prevent classloader leaks in new threads clear invocation manager before bootstrapping JMS
resourceadapter_.start(bootStrapContextImpl);
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@

import org.glassfish.hk2.api.PostConstruct;

import org.glassfish.api.event.Events;
import org.glassfish.api.event.EventTypes;
import org.glassfish.api.event.Events;
import org.glassfish.api.event.EventListener;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/

// Portions Copyright [2015] [C2B2 Consulting Limited]
package org.glassfish.enterprise.iiop.impl;

import com.sun.corba.ee.impl.javax.rmi.CORBA.StubDelegateImpl;
Expand Down Expand Up @@ -261,7 +261,8 @@ synchronized ORB getORB(Properties props) {
finestLog( "GlassFishORBManager.getORB->: {0}", orb);

if (orb == null) {
initORB(props);

initORB(props);
}

return orb;
Expand Down Expand Up @@ -553,7 +554,7 @@ private void initORB(Properties props) {
// OSGI mode and we're not in OSGI mode, orb initialization fails.
boolean useOSGI = false;

final ClassLoader prevCL = Utility.getClassLoader();
ClassLoader prevCL = Utility.getClassLoader();
try {
Utility.setContextClassLoader(GlassFishORBManager.class.getClassLoader());

Expand Down Expand Up @@ -582,8 +583,14 @@ private void initORB(Properties props) {

// Can't run with GlassFishORBManager.class.getClassLoader() as the context ClassLoader
orb = ORBFactory.create() ;
ORBFactory.initialize( orb, args, orbInitProperties, useOSGI);

prevCL = Utility.getClassLoader();
try {
Utility.setContextClassLoader(prevCL.getParent());

ORBFactory.initialize( orb, args, orbInitProperties, useOSGI);
} finally {
Utility.setContextClassLoader(prevCL);
}
// Done to indicate this is a server and
// needs to create listen ports.
try {
Expand Down Expand Up @@ -611,8 +618,12 @@ private void initORB(Properties props) {

rfm = (ReferenceFactoryManager) orb.resolve_initial_references(
ORBConstants.REFERENCE_FACTORY_MANAGER);


// ensure we don't inherit any Context Class Loaders when bootstrapping
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
new InitialGroupInfoService( orb ) ;
Thread.currentThread().setContextClassLoader(cl);

iiopUtils.setORB(orb);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,18 @@
// This software contains confidential and proprietary information of
// IBM Corp.
//----------------------------------------------------------------------------

//Portions Copyright [2015] [C2B2 Consulting Limited]
package com.sun.jts.CosTransactions;

import java.util.*;

import org.omg.CosTransactions.*;
import com.sun.jts.jtsxa.XID;

import com.sun.jts.trace.*;

import java.util.logging.Logger;
import java.util.logging.Level;
import com.sun.logging.LogDomains;
import com.sun.jts.utils.LogFormatter;

/**
* This class records state for timing out transactions, and runs a thread
Expand Down Expand Up @@ -150,7 +148,11 @@ static synchronized void initSetTimeout() {
if (isSetTimeout)
return;
isSetTimeout = true;

// to prevent classloader explicitly set context classloader

timeoutThread = new TimeoutThread();
timeoutThread.setContextClassLoader(timeoutThread.getClass().getClassLoader());
timeoutThread.start();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2015] [C2B2 Consulting Limited]

package com.sun.enterprise.glassfish.web;

Expand Down Expand Up @@ -80,7 +81,6 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

import static javax.xml.stream.XMLStreamConstants.*;

Expand Down Expand Up @@ -350,6 +350,7 @@ public boolean accept(File pathname) {
} else {
cloader.addJar(file.getPath().substring(baseFileLen),
new JarFile(file), file);
cloader.closeJARs(true);
}
} catch (Exception e) {
// Catch and ignore any exception in case the JAR file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Portions Copyright [2015] [C2B2 Consulting Limited]
package org.glassfish.web.loader;

import com.sun.appserv.BytecodePreprocessor;
Expand Down Expand Up @@ -2041,6 +2041,32 @@ public void closeJARs(boolean force) {
}
}
}

try {
// aggressively close parent jars

WeakHashMap<Closeable, Void> closeables;
Field closeField = URLClassLoader.class.getDeclaredField("closeables");
closeField.setAccessible(true);
closeables = (WeakHashMap<Closeable, Void>) closeField.get(this);
synchronized (closeables) {
Set<Closeable> keys = closeables.keySet();
for (Closeable c : keys) {
try {
if (c instanceof JarFile) {
c.close();
}
} catch (IOException ioex) {
}
}
closeables.clear();
}

} catch (Exception ex) {
Logger.getLogger(WebappClassLoader.class.getName()).log(Level.SEVERE, null, ex);
}


}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
import org.glassfish.api.deployment.archive.ReadableArchive;
import org.glassfish.cdi.CDILoggerInfo;
import org.glassfish.weld.connector.WeldUtils;
import org.glassfish.weld.connector.WeldUtils.*;
import org.glassfish.weld.ejb.EjbDescriptorImpl;
import org.jboss.weld.bootstrap.WeldBootstrap;
import org.jboss.weld.bootstrap.api.ServiceRegistry;
Expand All @@ -58,6 +57,7 @@
import javax.enterprise.inject.spi.InjectionTarget;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
Expand All @@ -71,7 +71,9 @@
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -752,7 +754,27 @@ private boolean isCDIAnnotatedClass(String className) {
protected BeansXml parseBeansXML(ReadableArchive archive, String beansXMLPath) throws IOException {
WeldBootstrap wb = context.getTransientAppMetaData(WeldDeployer.WELD_BOOTSTRAP,
WeldBootstrap.class);
return wb.parse(getBeansXMLFileURL(archive, beansXMLPath));
URL url = getBeansXMLFileURL(archive, beansXMLPath);
BeansXml result = wb.parse(url);
try {
// Ensure JarFile is closed
Class clazz = Class.forName("sun.net.www.protocol.jar.JarFileFactory", true, URL.class.getClassLoader());
Field fields[] = clazz.getDeclaredFields();
for (Field field : fields) {
if ("fileCache".equals(field.getName())) {
field.setAccessible(true);
HashMap<String,JarFile> files = (HashMap<String,JarFile>) field.get(null);
Set<JarFile> jars = new HashSet<>();
jars.addAll(files.values());
for (JarFile file : jars) {
file.close();
}
}
}
} catch (ClassNotFoundException | IllegalAccessException | SecurityException | IllegalArgumentException | IOException ex) {
logger.log(Level.SEVERE, null, ex);
}
return result;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2015] [C2B2 Consulting Llimited]

package org.glassfish.api.invocation;

Expand Down Expand Up @@ -92,7 +93,14 @@ public <T extends ComponentInvocation> T getPreviousInvocation()
public boolean isInvocationStackEmpty();

public java.util.List<? extends ComponentInvocation> getAllInvocations();


// useful to temp clear the invocation list for example when spawning a new Thread
// to prevent potential classloader leaks.
java.util.List<? extends ComponentInvocation> popAllInvocations();

// useful to temp clear the invocation list for example when spawning a new Thread
// to prevent potential classloader leaks.
public void putAllInvocations(java.util.List<? extends ComponentInvocation> invocations);

public void registerComponentInvocationHandler(ComponentInvocationType type,
RegisteredComponentInvocationHandler handler);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2015] [C2B2 Consulting Llimited]

package org.glassfish.api.invocation;

Expand Down Expand Up @@ -294,13 +295,33 @@ public <T extends ComponentInvocation> T getPreviousInvocation()
return (T) v.get(i - 2);
}

@Override
public List getAllInvocations() {
return frames.get();
}

@Override
public List<? extends ComponentInvocation> popAllInvocations() {
List<? extends ComponentInvocation> result = frames.get();
frames.set(null);
return result;
}

@Override
public void putAllInvocations(List<? extends ComponentInvocation> invocations) {
frames.set(new InvocationArray<>((List<ComponentInvocation>) invocations));
}

static class InvocationArray<T extends ComponentInvocation> extends java.util.ArrayList<T> {
private ComponentInvocationType invocationAttribute;

private InvocationArray(List<T> invocations) {
super(invocations);
}

private InvocationArray() {
}

public void setInvocationAttribute(ComponentInvocationType attribute) {
this.invocationAttribute = attribute;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2015] [C2B2 Consulting Limited]

package org.glassfish.internal.data;

Expand Down Expand Up @@ -448,11 +449,19 @@ public void clean(ExtendedDeploymentContext context) throws Exception {
// clean up the app level classloader
if (appClassLoader != null) {
try {
appServiceLocator.preDestroy(appClassLoader);
if (appServiceLocator != null) {
appServiceLocator.preDestroy(appClassLoader);
}
}
catch (Exception e) {
// Ignore, some failure in preDestroy
}
try {
PreDestroy.class.cast(appClassLoader).preDestroy();
} catch (Exception e) {
// ignore, the class loader does not need to be
// explicitely stopped or already stopped
}
appClassLoader = null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1095,7 +1095,7 @@ public void undeploy(String appName, ExtendedDeploymentContext context) {

// for DAS target, the undeploy should unload the application
// as well
if (DeploymentUtils.isDASTarget(params.target)) {
if (DeploymentUtils.isDASTarget(params.target) || DeploymentUtils.isDomainTarget(params.target)) {
unload(info, context);
}

Expand Down
Loading