Skip to content

Commit

Permalink
support JDK11-style create class
Browse files Browse the repository at this point in the history
  • Loading branch information
russgold committed Apr 11, 2019
1 parent 591009a commit 471b980
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,48 @@

package com.sun.corba.ee.impl.presentation.rmi.codegen;

import org.glassfish.pfl.dynamic.codegen.spi.Primitives;
import org.glassfish.pfl.dynamic.codegen.spi.Variable;
import org.glassfish.pfl.dynamic.codegen.spi.Expression;
import static java.lang.reflect.Modifier.ABSTRACT;
import static java.lang.reflect.Modifier.PRIVATE;
import static java.lang.reflect.Modifier.PUBLIC;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper.DUMP_AFTER_SETUP_VISITOR;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper.TRACE_BYTE_CODE_GENERATION;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper.USE_ASM_VERIFIER;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._Object;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._arg;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._body;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._call;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._cast;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._class;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._clear;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._const;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._constructor;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._define;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._end;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._expr;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._generate;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._method;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._new_array_init;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._package;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._return;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._setClassLoader;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._super;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._this;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._void;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper.splitClassName;

import java.io.PrintStream;
import java.lang.reflect.Method;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.glassfish.pfl.basic.contain.Pair;
import org.glassfish.pfl.dynamic.codegen.spi.Utility;
import org.glassfish.pfl.dynamic.codegen.spi.Expression;
import org.glassfish.pfl.dynamic.codegen.spi.MethodInfo;
import org.glassfish.pfl.dynamic.codegen.spi.Primitives;
import org.glassfish.pfl.dynamic.codegen.spi.Type;
import java.io.PrintStream ;

import java.lang.reflect.Method ;

import java.security.ProtectionDomain ;

import java.util.Properties ;
import java.util.List ;
import java.util.ArrayList ;

import static java.lang.reflect.Modifier.* ;

import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper.* ;
import org.glassfish.pfl.dynamic.codegen.spi.Utility;
import org.glassfish.pfl.dynamic.codegen.spi.Variable;

/** Generate a proxy with a specified base class.
*/
Expand Down Expand Up @@ -95,11 +117,13 @@ public CodegenProxyCreator( String className, Class sc,
* Note that the generated methods ignore exceptions.
* It is assumed that the invoke method may throw any
* desired exception.
* @param className the name of the generated class
* @param superClassName the name of the class extends by the generated class
* @param interfaces the interfaces implemented by the generated class
* @param methods the methods that the generated class implements
* @param pd the protection domain of the generated class
* @param cl the classloader in which to generate the class
* @param debug if true, generate debug messages
* @param ps a PrintStream to which the debug messages should be written
* @deprecated use {@link #create(Class, boolean, PrintStream)}
*/
@Deprecated
public Class<?> create( ProtectionDomain pd, ClassLoader cl,
boolean debug, PrintStream ps ) {

Expand Down Expand Up @@ -129,6 +153,70 @@ public Class<?> create( ProtectionDomain pd, ClassLoader cl,
return _generate( cl, pd, debug ? debugProps : emptyProps, ps ) ;
}

/** Construct a generator for a proxy class
* that implements the given interfaces and extends superClass.
* superClass must satisfy the following requirements:
* <ol>
* <li>It must have an accessible no args constructor</li>
* <li>It must have a method satisfying the signature
* <code> Object invoke( int methodNumber, Object[] args ) throws Throwable
* </code>
* </li>
* <li>The invoke method described above must be accessible
* to the generated class (generally either public or
* protected.</li>
* </ol>
* <p>
* Each method in methods is implemented by a method that:
* <ol>
* <li>Creates an array sized to hold the args</li>
* <li>Wraps args of primitive type in the appropriate wrapper.</li>
* <li>Copies each arg or wrapper arg into the array.</li>
* <li>Calls invoke with a method number corresponding to the
* index of the method in methods. Note that the invoke implementation
* must use the same method array to figure out which method has been
* invoked.</li>
* <li>Return the result (if any), extracting values from wrappers
* as needed to handle a return value of a primitive type.</li>
* </ol>
* <p>
* Note that the generated methods ignore exceptions.
* It is assumed that the invoke method may throw any
* desired exception.
* @param anchorClass a class in whose classloader the new class should be generated
* @param debug if true, generate debug messages
* @param ps a PrintStream to which the debug messages should be written
* @since 4.2.1
*/
public Class<?> create( Class<?> anchorClass,
boolean debug, PrintStream ps ) {

Pair<String,String> nm = splitClassName( className ) ;

_clear() ;
_setClassLoader( anchorClass.getClassLoader() ) ;
_package( nm.first() ) ;
_class( PUBLIC, nm.second(), superClass, interfaces ) ;

_constructor( PUBLIC ) ;
_body() ;
_expr(_super());
_end() ;

_method( PRIVATE, _Object(), "writeReplace" ) ;
_body() ;
_return(_call(_this(), "selfAsBaseClass" )) ;
_end() ;

int ctr=0 ;
for (MethodInfo method : methods)
createMethod( ctr++, method ) ;

_end() ; // of _class

return _generate( anchorClass, debug ? debugProps : emptyProps, ps ) ;
}

private static final Type objectArrayType = Type._array(_Object()) ;

private static void createMethod( int mnum, MethodInfo method ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,18 @@

package com.sun.corba.ee.impl.presentation.rmi.codegen ;

import java.util.Map ;

import java.security.ProtectionDomain ;
import com.sun.corba.ee.impl.presentation.rmi.StubFactoryDynamicBase;
import com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl;
import com.sun.corba.ee.impl.util.Utility;
import com.sun.corba.ee.spi.logging.ORBUtilSystemException;
import com.sun.corba.ee.spi.presentation.rmi.IDLNameTranslator;
import com.sun.corba.ee.spi.presentation.rmi.PresentationManager;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.AccessController;

import java.lang.reflect.InvocationHandler ;
import java.lang.reflect.Method ;

import com.sun.corba.ee.impl.util.Utility ;

import com.sun.corba.ee.spi.presentation.rmi.PresentationManager ;
import com.sun.corba.ee.spi.presentation.rmi.IDLNameTranslator ;

import com.sun.corba.ee.impl.presentation.rmi.StubFactoryDynamicBase ;
import com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl ;

import com.sun.corba.ee.spi.logging.ORBUtilSystemException ;
import java.util.Map;

public class StubFactoryCodegenImpl extends StubFactoryDynamicBase
{
Expand All @@ -45,85 +38,54 @@ public StubFactoryCodegenImpl( PresentationManager pm,
this.pm = pm ;
}

private Class<?> getStubClass()
{
Class<?> stubClass = null;

private Class<?> getStubClass() {
// IMPORTANT: A get & put to classData's dictionary can occur
// by two or more threads in this method at the same
// time. Therefore, classData must be synchronized here.

synchronized (classData) {
final Map<String,Object> dictionary = classData.getDictionary() ;
stubClass = (Class<?>)dictionary.get( CODEGEN_KEY ) ;
if (stubClass == null) {
final IDLNameTranslator nt = classData.getIDLNameTranslator() ;
final Class<?> theClass = classData.getMyClass() ;
final String stubClassName = Utility.dynamicStubName(
theClass.getName() ) ;
final Class<?> baseClass = CodegenStubBase.class ;
final Class<?>[] interfaces = nt.getInterfaces() ;
final Method[] methods = nt.getMethods() ;

final ProtectionDomain pd =
AccessController.doPrivileged(
new PrivilegedAction<ProtectionDomain>() {
public ProtectionDomain run() {
return theClass.getProtectionDomain() ;
}
}
) ;

// Create a StubGenerator that generates this stub class
final CodegenProxyCreator creator = new CodegenProxyCreator(
stubClassName, baseClass, interfaces, methods ) ;

// Invoke creator in a doPrivileged block if there is a security
// manager installed.
if (System.getSecurityManager() == null) {
stubClass = creator.create( pd, loader, pm.getDebug(),
pm.getPrintStream() ) ;
} else {
stubClass = AccessController.doPrivileged(
new PrivilegedAction<Class<?>>() {
public Class<?> run() {
return creator.create( pd, loader, pm.getDebug(),
pm.getPrintStream() ) ;
}
}
) ;
}

dictionary.put( CODEGEN_KEY, stubClass ) ;
}
final Map<String,Object> dictionary = classData.getDictionary();
return (Class<?>) dictionary.computeIfAbsent(CODEGEN_KEY, k -> createStubClass());
}
}

return stubClass ;
private Class<?> createStubClass() {
final IDLNameTranslator nt = classData.getIDLNameTranslator() ;
final Class<?> theClass = classData.getMyClass() ;
final String stubClassName = Utility.dynamicStubName(theClass.getName() ) ;
final Class<?> baseClass = CodegenStubBase.class ;
final Class<?>[] interfaces = nt.getInterfaces() ;
final Method[] methods = nt.getMethods() ;

// Create a StubGenerator that generates this stub class
final CodegenProxyCreator creator = new CodegenProxyCreator(stubClassName, baseClass, interfaces, methods);

// Invoke creator in a doPrivileged block if there is a security manager installed.
return System.getSecurityManager() == null
? createStubClass(creator)
: AccessController.doPrivileged((PrivilegedAction<Class<?>>) () -> createStubClass(creator)
);
}

public org.omg.CORBA.Object makeStub()
{
private Class<?> createStubClass(CodegenProxyCreator creator) {
return creator.create(classData.getMyClass(), pm.getDebug(), pm.getPrintStream());
}

public org.omg.CORBA.Object makeStub() {
final Class<?> stubClass = getStubClass( ) ;

CodegenStubBase stub = null ;

try {
// Added doPriv for issue 778
stub = AccessController.doPrivileged(
new PrivilegedExceptionAction<CodegenStubBase>() {
public CodegenStubBase run() throws Exception {
return CodegenStubBase.class.cast(
stubClass.newInstance() ) ;
}
}
stub = AccessController.doPrivileged(
(PrivilegedExceptionAction<CodegenStubBase>) () -> (CodegenStubBase) stubClass.newInstance()
) ;
} catch (Exception exc) {
wrapper.couldNotInstantiateStubClass( exc,
stubClass.getName() ) ;
wrapper.couldNotInstantiateStubClass(exc, stubClass.getName()) ;
}

InvocationHandler handler = new StubInvocationHandlerImpl( pm,
classData, stub ) ;
InvocationHandler handler = new StubInvocationHandlerImpl(pm, classData, stub) ;

stub.initialize( classData, handler ) ;

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
<maven.compiler.target>${jdkVersion}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sonar.dynamicAnalysis>false</sonar.dynamicAnalysis>
<pfl-version>4.0.1</pfl-version>
<pfl-version>4.1.0</pfl-version>
<gmbal-version>4.0.0</gmbal-version>
</properties>

Expand Down

0 comments on commit 471b980

Please sign in to comment.