Skip to content

Commit

Permalink
Issue #23616 Reduced cyclic dependencies between EJBUtils and others
Browse files Browse the repository at this point in the history
  • Loading branch information
dmatej committed Sep 27, 2021
1 parent 56db429 commit edd897c
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 204 deletions.
90 changes: 20 additions & 70 deletions appserver/ejb/ejb-container/src/main/java/com/sun/ejb/EJBUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import com.sun.ejb.codegen.AsmSerializableBeanGenerator;
import com.sun.ejb.codegen.ClassGeneratorFactory;
import com.sun.ejb.codegen.Generator;
import com.sun.ejb.codegen.GenericHomeGenerator;
import com.sun.ejb.codegen.Remote30WrapperGenerator;
import com.sun.ejb.codegen.RemoteGenerator;
Expand Down Expand Up @@ -176,64 +177,19 @@ public java.lang.Object run() {

}

private static String getClassPackageName(String intf) {
int dot = intf.lastIndexOf('.');
return dot == -1 ? null : intf.substring(0, dot);
}

/** @return the simple name of the class. For included classes returns includes dollar and wrapper class */
private static String getClassSimpleName(String intf) {
int dot = intf.lastIndexOf('.');
return dot == -1 ? intf : intf.substring(dot + 1);
}

/**
* Prepends __EJB31_Generated__ and adds _Intf__ to the simple class name.
*
* @param ejbClassName full class name
*/
public static String getGeneratedOptionalInterfaceName(String ejbClassName) {
String packageName = getClassPackageName(ejbClassName);
String simpleName = getClassSimpleName(ejbClassName);
String packageName = Generator.getPackageName(ejbClassName);
String simpleName = Generator.getBaseName(ejbClassName);
String optionalIntfName = "__EJB31_Generated__" + simpleName + "__Intf__";
return packageName == null ? optionalIntfName : packageName + "." + optionalIntfName;
}

/**
* Adds _Serializable to the original name.
*
* @param beanClass full class name
*/
public static String getGeneratedSerializableClassName(String beanClass) {
String packageName = getClassPackageName(beanClass);
String simpleName = getClassSimpleName(beanClass);
String generatedSimpleName = "_" + simpleName + "_Serializable";
return packageName == null ? generatedSimpleName : packageName + "." + generatedSimpleName;
}

/**
* Adds _Remote to the original name.
*
* @param businessIntf full class name
*/
public static String getGeneratedRemoteIntfName(String businessIntf) {
String packageName = getClassPackageName(businessIntf);
String simpleName = getClassSimpleName(businessIntf);
String generatedSimpleName = "_" + simpleName + "_Remote";
return packageName == null ? generatedSimpleName : packageName + "." + generatedSimpleName;
}

/**
* Adds _Wrapper to the original name.
*
* @param businessIntf full class name
*/
public static String getGeneratedRemoteWrapperName(String businessIntf) {
String packageName = getClassPackageName(businessIntf);
String simpleName = getClassSimpleName(businessIntf);
String generatedSimpleName = "_" + simpleName + "_Wrapper";
return packageName == null ? generatedSimpleName : packageName + "." + generatedSimpleName;
}

/**
* Actual jndi-name under which Remote ejb factory lives depends on
Expand Down Expand Up @@ -385,7 +341,7 @@ public static Object lookupRemote30BusinessObject(Object jndiObj, String busines
// is needed in a given JVM.
loadGeneratedRemoteBusinessClasses(businessInterface);

String generatedRemoteIntfName = EJBUtils.getGeneratedRemoteIntfName(businessInterface);
String generatedRemoteIntfName = RemoteGenerator.getGeneratedRemoteIntfName(businessInterface);
Method createMethod = genericEJBHome.getMethod("create", String.class);
java.rmi.Remote delegate = (java.rmi.Remote) createMethod.invoke(genericHomeObj, generatedRemoteIntfName);

Expand All @@ -401,10 +357,10 @@ public static Object lookupRemote30BusinessObject(Object jndiObj, String busines


public static Class loadGeneratedSerializableClass(ClassLoader loader, String className) throws Exception {
String generatedSerializableClassName = getGeneratedSerializableClassName(className);
String generatedSerializableClassName = AsmSerializableBeanGenerator.getGeneratedSerializableClassName(className);
Class developerClass = loader.loadClass(className);
AsmSerializableBeanGenerator gen = new AsmSerializableBeanGenerator(loader, developerClass,
generatedSerializableClassName);
AsmSerializableBeanGenerator gen =
new AsmSerializableBeanGenerator(loader, developerClass, generatedSerializableClassName);
return gen.generateSerializableSubclass();
}

Expand All @@ -418,15 +374,17 @@ public static void loadGeneratedRemoteBusinessClasses(String businessInterfaceNa
/**
* @param appClassLoader - used to verify existence of classes and for generating too.
* @param businessInterfaceName - this class must exist
* @return full class name of the generated remote interface
* @throws Exception
*/
public static void loadGeneratedRemoteBusinessClasses(ClassLoader appClassLoader, String businessInterfaceName)
public static String loadGeneratedRemoteBusinessClasses(ClassLoader appClassLoader, String businessInterfaceName)
throws Exception {
String generatedRemoteIntfName = EJBUtils.getGeneratedRemoteIntfName(businessInterfaceName);
String wrapperClassName = EJBUtils.getGeneratedRemoteWrapperName(businessInterfaceName);
String generatedRemoteIntfName = RemoteGenerator.getGeneratedRemoteIntfName(businessInterfaceName);
String wrapperClassName = Remote30WrapperGenerator.getGeneratedRemoteWrapperName(businessInterfaceName);
Class<?> generatedRemoteIntf = loadClassIgnoringExceptions(appClassLoader, generatedRemoteIntfName);
Class<?> generatedRemoteWrapper = loadClassIgnoringExceptions(appClassLoader, wrapperClassName);
if (generatedRemoteIntf != null && generatedRemoteWrapper != null) {
return;
return generatedRemoteIntfName;
}

Wrapper._setClassLoader(appClassLoader);
Expand All @@ -444,6 +402,7 @@ public static void loadGeneratedRemoteBusinessClasses(ClassLoader appClassLoader
// Make sure no classloader is bound to threadlocal: avoid possible classloader leak.
Wrapper._setClassLoader(null) ;
}
return generatedRemoteIntfName;
}


Expand Down Expand Up @@ -523,30 +482,21 @@ private static Class<?> loadClassIgnoringExceptions(ClassLoader classLoader, Str
}


public static RemoteBusinessWrapperBase createRemoteBusinessObject
(ClassLoader loader, String businessInterface,
java.rmi.Remote delegate)

throws Exception {

String wrapperClassName = EJBUtils.getGeneratedRemoteWrapperName
(businessInterface);

public static RemoteBusinessWrapperBase createRemoteBusinessObject(ClassLoader loader, String businessInterface,
java.rmi.Remote delegate) throws Exception {
String wrapperClassName = Remote30WrapperGenerator.getGeneratedRemoteWrapperName(businessInterface);
Class clientWrapperClass = loader.loadClass(wrapperClassName);

Constructor ctors[] = clientWrapperClass.getConstructors();

Constructor ctor = null;
for(Constructor next : ctors) {
if (next.getParameterTypes().length > 0 ) {
for (Constructor next : ctors) {
if (next.getParameterTypes().length > 0) {
ctor = next;
break;
}
}
Object obj = null;
if (ctor != null) {
obj = ctor.newInstance(new Object[]
{delegate, businessInterface});
obj = ctor.newInstance(delegate, businessInterface);
}
return (RemoteBusinessWrapperBase) obj;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -18,6 +19,7 @@

import com.sun.ejb.containers.BaseContainer;
import com.sun.ejb.EJBUtils;
import com.sun.ejb.codegen.RemoteGenerator;
import com.sun.ejb.containers.EjbContainerUtilImpl;
import com.sun.ejb.containers.RemoteBusinessWrapperBase;
import com.sun.enterprise.container.common.spi.util.JavaEEIOUtils;
Expand Down Expand Up @@ -69,6 +71,7 @@ public static final void setJavaEEIOUtils(JavaEEIOUtils javaEEIOUtils) {
* This code is needed to serialize non-Serializable objects that
* can be part of a bean's state. See EJB2.0 section 7.4.1.
*/
@Override
public Object replaceObject(Object obj)
throws IOException {
Object result = obj;
Expand Down Expand Up @@ -186,6 +189,7 @@ final class SerializableJNDIContext
}
}

@Override
public Object createObject()
throws IOException
{
Expand Down Expand Up @@ -273,6 +277,7 @@ final class SerializableS1ASEJBHomeReference
super(containerId);
}

@Override
public Object createObject()
throws IOException
{
Expand All @@ -299,14 +304,14 @@ public Object createObject()
final class SerializableS1ASEJBObjectReference
extends AbstractSerializableS1ASEJBReference
{
private byte[] instanceKey;
private final byte[] instanceKey;
private Object sfsbKey;
private long sfsbClientVersion;
private boolean haEnabled;

// If 3.0 Remote business view, the name of the remote business
// interface to which this stub corresponds.
private String remoteBusinessInterface;
private final String remoteBusinessInterface;

SerializableS1ASEJBObjectReference(long containerId, byte[] objKey,
int keySize, String remoteBusinessInterfaceName) {
Expand All @@ -330,6 +335,7 @@ boolean isHAEnabled() {
return haEnabled;
}

@Override
public Object createObject()
throws IOException
{
Expand All @@ -352,7 +358,7 @@ public Object createObject()

} else {

String generatedRemoteIntfName = EJBUtils.
String generatedRemoteIntfName = RemoteGenerator.
getGeneratedRemoteIntfName(remoteBusinessInterface);

java.rmi.Remote remoteRef = container.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -30,19 +31,31 @@
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

public class AsmSerializableBeanGenerator
implements Opcodes {
public class AsmSerializableBeanGenerator implements Opcodes {

private static final int INTF_FLAGS = ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES;

private byte[] classData = null;
private byte[] classData;
private Class loadedClass;
private final ClassLoader loader;

private Class loadedClass = null;
private ClassLoader loader;
private final Class baseClass;

private Class baseClass;
private final String subclassName;


/**
* Adds _Serializable to the original name.
*
* @param beanClass full class name
*/
public static String getGeneratedSerializableClassName(String beanClass) {
String packageName = Generator.getPackageName(beanClass);
String simpleName = Generator.getBaseName(beanClass);
String generatedSimpleName = "_" + simpleName + "_Serializable";
return packageName == null ? generatedSimpleName : packageName + "." + generatedSimpleName;
}

private String subclassName;

public AsmSerializableBeanGenerator(ClassLoader loader, Class baseClass, String serializableSubclassName) {
this.loader = loader;
Expand All @@ -51,9 +64,7 @@ public AsmSerializableBeanGenerator(ClassLoader loader, Class baseClass, String
}

public String getSerializableSubclassName() {

return subclassName;

}

public Class generateSerializableSubclass()
Expand Down Expand Up @@ -132,57 +143,13 @@ public Class generateSerializableSubclass()
cv.visitInsn(RETURN);
cv.visitMaxs(2, 2);


/**
Type[] eTypes = new Type[] { Type.getType(java.io.IOException.class)};
Method writeObjMethod = Method.getMethod("void writeObject (java.io.ObjectOutputStream)");
GeneratorAdapter writeObjMethodAdapter =
new GeneratorAdapter(ACC_PRIVATE, writeObjMethod, null, eTypes, tv);
Type ejbUtilsType = Type.getType(com.sun.ejb.EJBUtils.class);
Method ejbUtilsWrite = Method.getMethod
("void serializeObjectFields (java.lang.Class, java.lang.Object, java.lang.Object)");
writeObjMethodAdapter.push(Type.getType(ejbClass));
writeObjMethodAdapter.loadThis();
writeObjMethodAdapter.loadArg(0);
writeObjMethodAdapter.invokeStatic( ejbUtilsType, ejbUtilsWrite);
writeObjMethodAdapter.endMethod();
//
eTypes = new Type[] { Type.getType(java.io.IOException.class),
Type.getType(java.lang.ClassNotFoundException.class)};
Method readObjMethod = Method.getMethod("void readObject (java.io.ObjectInputStream)");
GeneratorAdapter readObjMethodAdapter =
new GeneratorAdapter(ACC_PRIVATE, readObjMethod, null, eTypes, tv);
Method ejbUtilsRead = Method.getMethod
("void deserializeObjectFields (java.lang.Class, java.lang.Object, java.lang.Object)");
readObjMethodAdapter.push(Type.getType(ejbClass));
readObjMethodAdapter.loadThis();
readObjMethodAdapter.loadArg(0);
readObjMethodAdapter.invokeStatic( ejbUtilsType, ejbUtilsRead);
readObjMethodAdapter.endMethod();
**/

tv.visitEnd();

classData = cw.toByteArray();

loadedClass = (Class) java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
@Override
public java.lang.Object run() {
return makeClass(subclassName, classData, baseClass.getProtectionDomain(), loader);
}
Expand All @@ -196,6 +163,7 @@ public java.lang.Object run() {
// using reflection. This requires the supressAccessChecks permission.
private static final java.lang.reflect.Method defineClassMethod = AccessController.doPrivileged(
new PrivilegedAction<java.lang.reflect.Method>() {
@Override
public java.lang.reflect.Method run() {
try {
java.lang.reflect.Method meth = ClassLoader.class.getDeclaredMethod(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,19 @@
public abstract class Generator implements ClassGeneratorFactory {

/**
* Get the package name from the class name.
*
* @param className class name.
* @return the package name.
* @return the package name or null.
*/
protected String getPackageName(String className) {
int dot = className.lastIndexOf('.');
if (dot == -1) {
return null;
}
return className.substring(0, dot);
public static String getPackageName(String fullClassName) {
int dot = fullClassName.lastIndexOf('.');
return dot == -1 ? null : fullClassName.substring(0, dot);
}


/**
* @param className
* @return simple class name (including wrapper class and dollar sign if it is internal class)
*/
protected String getBaseName(String className) {
int dot = className.lastIndexOf('.');
if (dot == -1) {
return className;
}
return className.substring(dot + 1);
public static String getBaseName(String fullClassName) {
int dot = fullClassName.lastIndexOf('.');
return dot == -1 ? fullClassName : fullClassName.substring(dot + 1);
}


Expand Down
Loading

0 comments on commit edd897c

Please sign in to comment.