Skip to content

Commit

Permalink
Avoiding creating bytecode for the same interface twice.
Browse files Browse the repository at this point in the history
Double checking the created interface from within the synchronized block.
  • Loading branch information
DanielSperry committed Apr 8, 2015
1 parent f02d097 commit 14e6e31
Showing 1 changed file with 47 additions and 43 deletions.
Expand Up @@ -26,7 +26,14 @@
*/
public class ActorFactoryGenerator
{
private static ClassPool classPool;
private final static ClassPool classPool;

static
{
classPool = new ClassPool(null);
classPool.appendSystemPath();
classPool.appendClassPath(new ClassClassPath(ActorFactoryGenerator.class));
}

private static class GenericActorFactory<T> extends ActorFactory<T>
{
Expand Down Expand Up @@ -101,31 +108,23 @@ public <T> ActorFactory<T> getFactoryFor(final Class<T> aInterface)
@SuppressWarnings("unchecked")
private <T> Class<T> makeReferenceClass(final Class<T> aInterface, final String interfaceFullName, final int interfaceId, final String referenceFullName) throws NotFoundException, CannotCompileException
{
try
Class clazz = lookup(referenceFullName);
if (clazz != null)
{
return (Class<T>) Class.forName(referenceFullName);
}
catch (final Exception ex)
{
// ignore;
}
final ClassPool pool = getClassPool();
try
{
return (Class<T>) pool.getClassLoader().loadClass(referenceFullName);
}
catch (final Exception ex2)
{
// ignore;
}

if ("ISomeChatObserver".equals(aInterface.getSimpleName()))
{
System.out.println();
return clazz;
}

synchronized (aInterface)
{
// trying again from within the synchronized block.
clazz = lookup(referenceFullName);
if (clazz != null)
{
return clazz;
}

final ClassPool pool = classPool;

final CtClass cc = pool.makeClass(referenceFullName);
final CtClass ccInterface = pool.get(aInterface.getName());
final CtClass ccActorReference = pool.get(ActorReference.class.getName());
Expand Down Expand Up @@ -159,26 +158,22 @@ private <T> Class<T> makeReferenceClass(final Class<T> aInterface, final String

private <T> Class<?> makeInvokerClass(final Class<T> aInterface, final String invokerFullName) throws NotFoundException, CannotCompileException
{
try
{
return Class.forName(invokerFullName);
}
catch (final Exception ex)
Class clazz = lookup(invokerFullName);
if (clazz != null)
{
// ignore;
}
final ClassPool pool = getClassPool();
try
{
return pool.getClassLoader().loadClass(invokerFullName);
}
catch (final Exception ex2)
{
// ignore;
return clazz;
}

synchronized (aInterface)
{
// trying again from within the synchronized block.
clazz = lookup(invokerFullName);
if (clazz != null)
{
return clazz;
}
ClassPool pool = classPool;

final CtClass cc = pool.makeClass(invokerFullName);
final CtClass ccInterface = pool.get(aInterface.getName());
final CtClass ccActorInvoker = pool.get(ActorInvoker.class.getName());
Expand Down Expand Up @@ -226,16 +221,25 @@ private <T> Class<?> makeInvokerClass(final Class<T> aInterface, final String in
}
}

private static synchronized ClassPool getClassPool()
private Class lookup(String className)
{
if (classPool == null)
try
{
classPool = new ClassPool(null);
classPool.appendSystemPath();
classPool.appendClassPath(new ClassClassPath(ActorFactoryGenerator.class));
return Class.forName(className);
}

return classPool;
catch (final Exception ex)
{
// ignore;
}
try
{
return classPool.getClassLoader().loadClass(className);
}
catch (final Exception ex2)
{
// ignore;
}
return null;
}

}

0 comments on commit 14e6e31

Please sign in to comment.