[jboss-svn-commits] JBL Code SVN: r32483 - in labs/jbossrules/trunk: drools-compiler/src/main/java/org/drools/compiler and 6 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Apr 8 23:08:58 EDT 2010
Author: tirelli
Date: 2010-04-08 23:08:57 -0400 (Thu, 08 Apr 2010)
New Revision: 32483
Modified:
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ClassLoaderUtil.java
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/CompositeClassLoader.java
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SessionConfiguration.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ClassPathResource.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/DroolsCompositeClassLoader.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/JavaDialectRuntimeData.java
Log:
JBRULES-2067: adding support to class resolution caching on user and system classloaders to improve compilation performance.
Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ClassLoaderUtil.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ClassLoaderUtil.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ClassLoaderUtil.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -1,39 +1,37 @@
package org.drools.util;
-import java.util.ArrayList;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map.Entry;
-
public class ClassLoaderUtil {
- public static ClassLoader getClassLoader(final ClassLoader classLoader, Class cls) {
+ public static CompositeClassLoader getClassLoader(final ClassLoader classLoader,
+ final Class< ? > cls,
+ final boolean enableCache) {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
- ClassLoader currentClassLoader = ( cls != null ) ? cls.getClassLoader() : ClassLoaderUtil.class.getClassLoader();
- ClassLoader systemClassLoader = Class.class.getClassLoader().getSystemClassLoader();
-
- CompositeClassLoader cl = new CompositeClassLoader( null );
-
- if (classLoader != null ) {
+ ClassLoader currentClassLoader = (cls != null) ? cls.getClassLoader() : ClassLoaderUtil.class.getClassLoader();
+ ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+
+ CompositeClassLoader cl = new CompositeClassLoader( null );
+
+ if ( classLoader != null ) {
// the user specified classloader
- cl.addClassLoader(classLoader);
+ cl.addClassLoader( classLoader );
}
-
- if (currentClassLoader != null ) {
+
+ if ( currentClassLoader != null ) {
// the current classloader, typically from a drools-core or drools-compiler class
- cl.addClassLoader(currentClassLoader);
- }
-
- if (contextClassLoader != null ) {
+ cl.addClassLoader( currentClassLoader );
+ }
+
+ if ( contextClassLoader != null ) {
// context classloader
- cl.addClassLoader(contextClassLoader);
- }
-
- if (systemClassLoader != null ) {
+ cl.addClassLoader( contextClassLoader );
+ }
+
+ if ( systemClassLoader != null ) {
// system classloader
- cl.addClassLoader(systemClassLoader);
- }
-
+ cl.addClassLoader( systemClassLoader );
+ }
+
+ cl.setCachingEnabled( enableCache );
+
return cl;
-
- }
+ }
}
Modified: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/CompositeClassLoader.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/CompositeClassLoader.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/CompositeClassLoader.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -5,19 +5,32 @@
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicReference;
public class CompositeClassLoader extends ClassLoader {
/* Assumption: modifications are really rare, but iterations are frequent. */
- private final List<ClassLoader> classLoaders = new CopyOnWriteArrayList<ClassLoader>();
+ private final List<ClassLoader> classLoaders = new CopyOnWriteArrayList<ClassLoader>();
+ private final AtomicReference<Loader> loader = new AtomicReference<Loader>();
public CompositeClassLoader(final ClassLoader parentClassLoader) {
super( null );
+ loader.set( new DefaultLoader() );
}
+ public synchronized void setCachingEnabled(boolean enabled) {
+ if ( enabled && loader.get() instanceof DefaultLoader ) {
+ loader.set( new CachingLoader() );
+ } else if ( !enabled && loader.get() instanceof CachingLoader ) {
+ loader.set( DefaultLoader.INSTANCE );
+ }
+ }
+
public synchronized void addClassLoader(final ClassLoader classLoader) {
/* NB: we need synchronized here even though we use a COW list:
* two threads may try to add the same new class loader, so we need
@@ -30,6 +43,7 @@
}
}
this.classLoaders.add( classLoader );
+ this.loader.get().reset();
}
public synchronized void removeClassLoader(final ClassLoader classLoader) {
@@ -37,6 +51,7 @@
* addClassLoader(x) and removeClassLoader(x).
*/
classLoaders.remove( classLoader );
+ this.loader.get().reset();
}
/**
@@ -45,25 +60,9 @@
*/
public Class< ? > loadClass(final String name,
final boolean resolve) throws ClassNotFoundException {
- // search the child ClassLoaders
- Class< ? > cls = null;
-
- for ( final ClassLoader classLoader : this.classLoaders ) {
- try {
- cls = Class.forName( name, true, classLoader );
- } catch ( ClassNotFoundException e ) {
- // swallow as we need to check more classLoaders
- }
- if ( cls != null ) {
- break;
- }
- }
-
- if ( resolve ) {
- resolveClass( cls );
- }
-
- return cls;
+ return loader.get().load( this,
+ name,
+ resolve );
}
/**
@@ -111,10 +110,119 @@
}
}
+ public void dumpStats() {
+ System.out.println( loader.toString() );
+ }
+
+ private static interface Loader {
+ public Class< ? > load(final CompositeClassLoader cl,
+ final String name,
+ final boolean resolve);
+
+ public void reset();
+ }
+
+ private static class DefaultLoader
+ implements
+ Loader {
+
+ // this class is stateless, so lets make a singleton of it
+ public static final DefaultLoader INSTANCE = new DefaultLoader();
+
+ private DefaultLoader() {
+ }
+
+ public Class< ? > load(final CompositeClassLoader cl,
+ final String name,
+ final boolean resolve) {
+ // search the child ClassLoaders
+ Class< ? > cls = null;
+
+ for ( final ClassLoader classLoader : cl.classLoaders ) {
+ try {
+ cls = Class.forName( name,
+ true,
+ classLoader );
+ } catch ( ClassNotFoundException e ) {
+ // swallow as we need to check more classLoaders
+ }
+ if ( cls != null ) {
+ break;
+ }
+ }
+
+ if ( resolve ) {
+ cl.resolveClass( cls );
+ }
+
+ return cls;
+ }
+
+ public void reset() {
+ // nothing to do
+ }
+ }
+
+ private static class CachingLoader
+ implements
+ Loader {
+
+ private final Map<String, Object> classLoaderResultMap = new HashMap<String, Object>();
+ public long successfulCalls = 0;
+ public long failedCalls = 0;
+ public long cacheHits = 0;
+
+ public Class< ? > load(final CompositeClassLoader cl,
+ final String name,
+ final boolean resolve) {
+ if ( classLoaderResultMap.containsKey( name ) ) {
+ cacheHits++;
+ return (Class< ? >) classLoaderResultMap.get( name );
+ }
+ // search the child ClassLoaders
+ Class< ? > cls = null;
+
+ for ( final ClassLoader classLoader : cl.classLoaders ) {
+ try {
+ cls = Class.forName( name,
+ true,
+ classLoader );
+ } catch ( ClassNotFoundException e ) {
+ // swallow as we need to check more classLoaders
+ }
+ if ( cls != null ) {
+ break;
+ }
+ }
+
+ if ( resolve ) {
+ cl.resolveClass( cls );
+ }
+
+ classLoaderResultMap.put( name,
+ cls );
+ if ( cls != null ) {
+ this.successfulCalls++;
+ } else {
+ this.failedCalls++;
+ }
+
+ return cls;
+ }
+
+ public void reset() {
+ this.successfulCalls = this.failedCalls = this.cacheHits = 0;
+ }
+
+ public String toString() {
+ return new StringBuilder().append( "TotalCalls: " ).append( successfulCalls + failedCalls + cacheHits ).append( " CacheHits: " ).append( cacheHits ).append( " successfulCalls: " ).append( successfulCalls ).append( " FailedCalls: " ).append( failedCalls ).toString();
+ }
+ }
+
private static class CompositeEnumeration<URL>
implements
Enumeration<URL> {
- private List<URL> list;
+ private List<URL> list;
private Iterator<URL> it;
public void addEnumeration(Enumeration<URL> enumeration) {
@@ -122,15 +230,15 @@
// don't add it, if it's empty
return;
}
-
+
if ( this.it != null ) {
throw new IllegalStateException( "cannot add more enumerations while iterator" );
}
-
+
if ( this.list == null ) {
this.list = new ArrayList<URL>();
}
-
+
while ( enumeration.hasMoreElements() ) {
this.list.add( enumeration.nextElement() );
}
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -126,7 +126,7 @@
*/
private final String defaultDialect;
- private DroolsCompositeClassLoader rootClassLoader;
+ private DroolsCompositeClassLoader rootClassLoader;
private Map<String, Class< ? >> globals;
@@ -135,9 +135,9 @@
private List<DSLTokenizedMappingFile> dslFiles;
private TimeIntervalParser timeParser;
-
- protected DateFormats dateFormats;
+ protected DateFormats dateFormats;
+
/**
* Use this when package is starting from scratch.
*/
@@ -182,14 +182,15 @@
} else {
this.configuration = configuration;
}
-
+
this.dateFormats = null;//(DateFormats) this.environment.get( EnvironmentName.DATE_FORMATS );
if ( this.dateFormats == null ) {
this.dateFormats = new DateFormatsImpl();
//this.environment.set( EnvironmentName.DATE_FORMATS , this.dateFormats );
- }
+ }
- this.rootClassLoader = new DroolsCompositeClassLoader( this.configuration.getClassLoader() );
+ this.rootClassLoader = new DroolsCompositeClassLoader( this.configuration.getClassLoader(),
+ this.configuration.isClassLoaderCacheEnabled() );
this.defaultDialect = this.configuration.getDefaultDialect();
@@ -216,14 +217,15 @@
if ( ruleBase != null ) {
this.rootClassLoader = ((InternalRuleBase) ruleBase).getRootClassLoader();
} else {
- this.rootClassLoader = new DroolsCompositeClassLoader( this.configuration.getClassLoader() );
+ this.rootClassLoader = new DroolsCompositeClassLoader( this.configuration.getClassLoader(),
+ this.configuration.isClassLoaderCacheEnabled() );
}
-
+
this.dateFormats = null;//(DateFormats) this.environment.get( EnvironmentName.DATE_FORMATS );
if ( this.dateFormats == null ) {
this.dateFormats = new DateFormatsImpl();
//this.environment.set( EnvironmentName.DATE_FORMATS , this.dateFormats );
- }
+ }
// FIXME, we need to get drools to support "default" namespace.
//this.defaultNamespace = pkg.getName();
@@ -341,9 +343,9 @@
DefaultExpander expander = getDslExpander();
try {
- if (expander == null) {
- expander = new DefaultExpander();
- }
+ if ( expander == null ) {
+ expander = new DefaultExpander();
+ }
String str = expander.expand( resource.getReader() );
if ( expander.hasErrors() ) {
this.results.addAll( expander.getErrors() );
@@ -371,15 +373,15 @@
DefaultExpander expander = getDslExpander();
try {
- String str;
- if (expander != null) {
- str = expander.expand( new StringReader( drl ) );
+ String str;
+ if ( expander != null ) {
+ str = expander.expand( new StringReader( drl ) );
if ( expander.hasErrors() ) {
this.results.addAll( expander.getErrors() );
}
- } else {
- str = drl;
- }
+ } else {
+ str = drl;
+ }
final PackageDescr pkg = parser.parse( str );
this.results.addAll( parser.getErrors() );
@@ -487,7 +489,7 @@
addProcessFromXml( resource );
} else if ( ResourceType.BPMN2.equals( type ) ) {
((InternalResource) resource).setResourceType( type );
- BPMN2ProcessFactory.configurePackageBuilder(this);
+ BPMN2ProcessFactory.configurePackageBuilder( this );
addProcessFromXml( resource );
} else if ( ResourceType.DTABLE.equals( type ) ) {
((InternalResource) resource).setResourceType( type );
@@ -498,16 +500,19 @@
addPackageFromDrl( new StringReader( string ) );
} else if ( ResourceType.PKG.equals( type ) ) {
InputStream is = resource.getInputStream();
- Package pkg = (Package) DroolsStreamUtils.streamIn( is, this.configuration.getClassLoader() );
+ Package pkg = (Package) DroolsStreamUtils.streamIn( is,
+ this.configuration.getClassLoader() );
is.close();
addPackage( pkg );
} else if ( ResourceType.CHANGE_SET.equals( type ) ) {
((InternalResource) resource).setResourceType( type );
XmlChangeSetReader reader = new XmlChangeSetReader( this.configuration.getSemanticModules() );
if ( resource instanceof ClassPathResource ) {
- reader.setClassLoader( ((ClassPathResource) resource).getClassLoader(), ((ClassPathResource) resource).getClazz() );
+ reader.setClassLoader( ((ClassPathResource) resource).getClassLoader(),
+ ((ClassPathResource) resource).getClazz() );
} else {
- reader.setClassLoader( this.configuration.getClassLoader() , null);
+ reader.setClassLoader( this.configuration.getClassLoader(),
+ null );
}
ChangeSet changeSet = reader.read( resource.getReader() );
if ( changeSet == null ) {
@@ -1230,10 +1235,10 @@
public Map<String, PackageRegistry> getPackageRegistry() {
return this.pkgRegistryMap;
}
-
+
public DateFormats getDateFormats() {
return this.dateFormats;
- }
+ }
/**
* Returns an expander for DSLs (only if there is a DSL configured for this package).
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -30,6 +30,7 @@
import org.drools.base.evaluators.EvaluatorRegistry;
import org.drools.builder.KnowledgeBuilderConfiguration;
import org.drools.builder.conf.AccumulateFunctionOption;
+import org.drools.builder.conf.ClassLoaderCacheOption;
import org.drools.builder.conf.DefaultDialectOption;
import org.drools.builder.conf.DefaultPackageNameOption;
import org.drools.builder.conf.DumpDirOption;
@@ -71,6 +72,7 @@
* drools.accumulate.function.<function name> = <qualified class>
* drools.evaluator.<ident> = <qualified class>
* drools.dump.dir = <String>
+ * drools.classLoaderCacheEnabled = true|false
*
* default dialect is java.
* Available preconfigured Accumulate functions are:
@@ -88,28 +90,30 @@
private Map<String, DialectConfiguration> dialectConfigurations;
- private DefaultDialectOption defaultDialect;
+ private DefaultDialectOption defaultDialect;
- private ClassLoader classLoader;
+ private CompositeClassLoader classLoader;
- private ChainedProperties chainedProperties;
+ private ChainedProperties chainedProperties;
- private Map<String, AccumulateFunction> accumulateFunctions;
+ private Map<String, AccumulateFunction> accumulateFunctions;
- private EvaluatorRegistry evaluatorRegistry;
+ private EvaluatorRegistry evaluatorRegistry;
- private SemanticModules semanticModules;
+ private SemanticModules semanticModules;
- private ProcessNodeBuilderRegistry nodeBuilderRegistry;
+ private ProcessNodeBuilderRegistry nodeBuilderRegistry;
- private File dumpDirectory;
+ private File dumpDirectory;
- private boolean allowMultipleNamespaces = true;
+ private boolean allowMultipleNamespaces = true;
- private boolean processStringEscapes = true;
+ private boolean processStringEscapes = true;
- private String defaultPackageName;
+ private boolean classLoaderCache = true;
+ private String defaultPackageName;
+
public boolean isAllowMultipleNamespaces() {
return allowMultipleNamespaces;
}
@@ -162,12 +166,16 @@
this.chainedProperties = new ChainedProperties( "packagebuilder.conf",
this.classLoader,
- true);
+ true );
if ( properties != null ) {
this.chainedProperties.addProperties( properties );
}
+ setProperty( ClassLoaderCacheOption.PROPERTY_NAME,
+ this.chainedProperties.getProperty( ClassLoaderCacheOption.PROPERTY_NAME,
+ "true" ) );
+
this.dialectConfigurations = new HashMap<String, DialectConfiguration>();
buildDialectConfigurationMap();
@@ -181,7 +189,7 @@
setProperty( ProcessStringEscapesOption.PROPERTY_NAME,
this.chainedProperties.getProperty( ProcessStringEscapesOption.PROPERTY_NAME,
"true" ) );
-
+
setProperty( DefaultPackageNameOption.PROPERTY_NAME,
this.chainedProperties.getProperty( DefaultPackageNameOption.PROPERTY_NAME,
"defaultpkg" ) );
@@ -207,6 +215,8 @@
setDefaultPackageName( value );
} else if ( name.equals( ProcessStringEscapesOption.PROPERTY_NAME ) ) {
setProcessStringEscapes( Boolean.parseBoolean( value ) );
+ } else if ( name.equals( ClassLoaderCacheOption.PROPERTY_NAME ) ) {
+ setClassLoaderCacheEnabled( Boolean.parseBoolean( value ) );
}
}
@@ -225,13 +235,15 @@
AccumulateFunction function = this.accumulateFunctions.get( name.substring( index ) );
return function != null ? function.getClass().getName() : null;
} else if ( name.startsWith( EvaluatorOption.PROPERTY_NAME ) ) {
- String key = name.substring( name.lastIndexOf( '.' )+1 );
- EvaluatorDefinition evalDef = this.evaluatorRegistry.getEvaluatorDefinition( key );
+ String key = name.substring( name.lastIndexOf( '.' ) + 1 );
+ EvaluatorDefinition evalDef = this.evaluatorRegistry.getEvaluatorDefinition( key );
return evalDef != null ? evalDef.getClass().getName() : null;
} else if ( name.equals( DumpDirOption.PROPERTY_NAME ) ) {
return this.dumpDirectory != null ? this.dumpDirectory.toString() : null;
} else if ( name.equals( ProcessStringEscapesOption.PROPERTY_NAME ) ) {
return String.valueOf( isProcessStringEscapes() );
+ } else if ( name.equals( ClassLoaderCacheOption.PROPERTY_NAME ) ) {
+ return String.valueOf( isClassLoaderCacheEnabled() );
}
return null;
}
@@ -318,7 +330,9 @@
/** Use this to override the classLoader that will be used for the rules. */
public void setClassLoader(final ClassLoader classLoader) {
- this.classLoader = ClassLoaderUtil.getClassLoader( classLoader, getClass() );
+ this.classLoader = ClassLoaderUtil.getClassLoader( classLoader,
+ getClass(),
+ isClassLoaderCacheEnabled() );
}
public void addSemanticModule(SemanticModule module) {
@@ -616,11 +630,20 @@
public void setProcessStringEscapes(boolean processStringEscapes) {
this.processStringEscapes = processStringEscapes;
}
-
+
+ public boolean isClassLoaderCacheEnabled() {
+ return classLoaderCache;
+ }
+
+ public void setClassLoaderCacheEnabled(boolean classLoaderCacheEnabled) {
+ this.classLoaderCache = classLoaderCacheEnabled;
+ this.classLoader.setCachingEnabled( this.classLoaderCache );
+ }
+
public String getDefaultPackageName() {
return defaultPackageName;
}
-
+
public void setDefaultPackageName(String defaultPackageName) {
this.defaultPackageName = defaultPackageName;
}
@@ -632,16 +655,18 @@
} else if ( DumpDirOption.class.equals( option ) ) {
return (T) DumpDirOption.get( this.dumpDirectory );
} else if ( ProcessStringEscapesOption.class.equals( option ) ) {
- return (T) ( this.processStringEscapes ? ProcessStringEscapesOption.YES : ProcessStringEscapesOption.NO );
+ return (T) (this.processStringEscapes ? ProcessStringEscapesOption.YES : ProcessStringEscapesOption.NO);
} else if ( DefaultPackageNameOption.class.equals( option ) ) {
return (T) DefaultPackageNameOption.get( this.defaultPackageName );
+ } else if ( ClassLoaderCacheOption.class.equals( option ) ) {
+ return (T) (this.classLoaderCache ? ClassLoaderCacheOption.ENABLED : ClassLoaderCacheOption.DISABLED);
}
return null;
}
@SuppressWarnings("unchecked")
public <T extends MultiValueKnowledgeBuilderOption> T getOption(Class<T> option,
- String key) {
+ String key) {
if ( AccumulateFunctionOption.class.equals( option ) ) {
return (T) AccumulateFunctionOption.get( key,
this.accumulateFunctions.get( key ) );
@@ -666,7 +691,8 @@
this.processStringEscapes = ((ProcessStringEscapesOption) option).isProcessStringEscapes();
} else if ( option instanceof DefaultPackageNameOption ) {
setDefaultPackageName( ((DefaultPackageNameOption) option).getPackageName() );
+ } else if ( option instanceof ClassLoaderCacheOption ) {
+ setClassLoaderCacheEnabled( ((ClassLoaderCacheOption) option).isClassLoaderCacheEnabled() );
}
}
-
}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -1088,7 +1088,8 @@
assertFalse( builder.hasErrors() );
Package bp = builder.getPackage();
- DroolsCompositeClassLoader rootClassloader = new DroolsCompositeClassLoader( Thread.currentThread().getContextClassLoader() );
+ DroolsCompositeClassLoader rootClassloader = new DroolsCompositeClassLoader( Thread.currentThread().getContextClassLoader(),
+ false );
JavaDialectRuntimeData dialectData = (JavaDialectRuntimeData) bp.getDialectRuntimeRegistry().getDialectData( "java" );
dialectData.onAdd( bp.getDialectRuntimeRegistry(),
rootClassloader );
@@ -1392,8 +1393,9 @@
final PackageBuilder builder = new PackageBuilder();
final PackageDescr packageDescr = new PackageDescr( "p1" );
- final TypeDeclarationDescr typeDeclDescr = new TypeDeclarationDescr(StockTick.class.getName());
- typeDeclDescr.addMetaAttribute( "role", "event" );
+ final TypeDeclarationDescr typeDeclDescr = new TypeDeclarationDescr( StockTick.class.getName() );
+ typeDeclDescr.addMetaAttribute( "role",
+ "event" );
packageDescr.addTypeDeclaration( typeDeclDescr );
final RuleDescr ruleDescr = new RuleDescr( "rule-1" );
packageDescr.addRule( ruleDescr );
@@ -1509,34 +1511,34 @@
public void setResource(Resource resource) {
}
- public String[] getGlobalNames() {
- return null;
- }
+ public String[] getGlobalNames() {
+ return null;
+ }
- public Map<String, String> getGlobals() {
- return null;
- }
+ public Map<String, String> getGlobals() {
+ return null;
+ }
- public List<String> getImports() {
- return null;
- }
+ public List<String> getImports() {
+ return null;
+ }
- public void setGlobals(Map<String, String> globals) {
- }
+ public void setGlobals(Map<String, String> globals) {
+ }
- public void setImports(List<String> imports) {
- }
+ public void setImports(List<String> imports) {
+ }
- public List<String> getFunctionImports() {
- // TODO Auto-generated method stub
- return null;
- }
+ public List<String> getFunctionImports() {
+ // TODO Auto-generated method stub
+ return null;
+ }
- public void setFunctionImports(List<String> functionImports) {
- // TODO Auto-generated method stub
-
- }
+ public void setFunctionImports(List<String> functionImports) {
+ // TODO Auto-generated method stub
+ }
+
}
class MockActivation
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -92,10 +92,12 @@
import org.drools.WorkingMemory;
import org.drools.Cheesery.Maturity;
import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderConfiguration;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
+import org.drools.builder.conf.ClassLoaderCacheOption;
import org.drools.common.AbstractWorkingMemory;
import org.drools.common.DefaultAgenda;
import org.drools.common.DefaultFactHandle;
@@ -145,6 +147,7 @@
import org.drools.runtime.rule.WorkingMemoryEntryPoint;
import org.drools.spi.ConsequenceExceptionHandler;
import org.drools.spi.GlobalResolver;
+import org.drools.util.CompositeClassLoader;
/** Run all the tests with the ReteOO engine implementation */
public class MiscTest extends TestCase {
@@ -6935,7 +6938,22 @@
session.setGlobal( "list", list );
session.fireAllRules();
assertEquals(1, list.size() );
+ }
+
+ public void testClassLoaderHits() throws Exception {
+ final KnowledgeBuilderConfiguration conf = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration();
+ //conf.setOption( ClassLoaderCacheOption.DISABLED );
+ final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder( conf );
+ kbuilder.add( ResourceFactory.newInputStreamResource( getClass().getResourceAsStream( "test_GeneratedBeansMVEL.drl" ) ),
+ ResourceType.DRL );
+ kbuilder.add( ResourceFactory.newInputStreamResource( getClass().getResourceAsStream( "test_GeneratedBeans.drl" ) ),
+ ResourceType.DRL );
+ kbuilder.add( ResourceFactory.newInputStreamResource( getClass().getResourceAsStream( "test_NullFieldOnCompositeSink.drl" ) ),
+ ResourceType.DRL );
+ assertFalse( kbuilder.getErrors().toString(),
+ kbuilder.hasErrors() );
+
+ //((CompositeClassLoader)((PackageBuilderConfiguration)conf).getClassLoader()).dumpStats();
}
-
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -28,6 +28,7 @@
import java.util.Set;
import java.util.Map.Entry;
+import org.drools.builder.conf.ClassLoaderCacheOption;
import org.drools.common.AgendaGroupFactory;
import org.drools.common.ArrayAgendaGroupFactory;
import org.drools.common.PriorityQueueAgendaGroupFactory;
@@ -115,6 +116,7 @@
* drools.maxThreads = <-1|1..n>
* drools.multithreadEvaluation = <true|false>
* drools.mbeans = <enabled|disabled>
+ * drools.classLoaderCacheEnabled = <true|false>
* </pre>
*/
public class RuleBaseConfiguration
@@ -143,6 +145,7 @@
private String executorService;
private String consequenceExceptionHandler;
private String ruleBaseUpdateHandler;
+ private boolean classLoaderCacheEnabled;
private EventProcessingOption eventProcessingMode;
@@ -164,7 +167,7 @@
private ProcessInstanceFactoryRegistry processInstanceFactoryRegistry;
private NodeInstanceFactoryRegistry processNodeInstanceFactoryRegistry;
- private transient ClassLoader classLoader;
+ private transient CompositeClassLoader classLoader;
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject( chainedProperties );
@@ -190,6 +193,7 @@
out.writeBoolean( multithread );
out.writeInt( maxThreads );
out.writeObject( eventProcessingMode );
+ out.writeBoolean( classLoaderCacheEnabled );
}
public void readExternal(ObjectInput in) throws IOException,
@@ -217,6 +221,7 @@
multithread = in.readBoolean();
maxThreads = in.readInt();
eventProcessingMode = (EventProcessingOption) in.readObject();
+ classLoaderCacheEnabled = in.readBoolean();
}
/**
@@ -307,6 +312,8 @@
setEventProcessingMode( EventProcessingOption.determineEventProcessingMode( StringUtils.isEmpty( value ) ? "cloud" : value ) );
} else if ( name.equals( MBeansOption.PROPERTY_NAME ) ) {
setMBeansEnabled( MBeansOption.isEnabled( value ) );
+ } else if ( name.equals( ClassLoaderCacheOption.PROPERTY_NAME ) ) {
+ setClassLoaderCacheEnabled( StringUtils.isEmpty( value ) ? true : Boolean.valueOf( value ) );
}
}
@@ -358,6 +365,8 @@
return getEventProcessingMode().getMode();
} else if ( name.equals( MBeansOption.PROPERTY_NAME ) ) {
return isMBeansEnabled() ? "enabled" : "disabled";
+ } else if ( name.equals( ClassLoaderCacheOption.PROPERTY_NAME ) ) {
+ return Boolean.toString( isClassLoaderCacheEnabled() );
}
return null;
@@ -383,7 +392,9 @@
setClassLoader( classLoader );
- this.chainedProperties = new ChainedProperties( "rulebase.conf", this.classLoader, true );
+ this.chainedProperties = new ChainedProperties( "rulebase.conf",
+ this.classLoader,
+ true );
if ( properties != null ) {
this.chainedProperties.addProperties( properties );
@@ -443,12 +454,15 @@
setMaxThreads( Integer.parseInt( this.chainedProperties.getProperty( MaxThreadsOption.PROPERTY_NAME,
"3" ) ) );
-
+
setEventProcessingMode( EventProcessingOption.determineEventProcessingMode( this.chainedProperties.getProperty( EventProcessingOption.PROPERTY_NAME,
"cloud" ) ) );
-
+
setMBeansEnabled( MBeansOption.isEnabled( this.chainedProperties.getProperty( MBeansOption.PROPERTY_NAME,
"disabled" ) ) );
+
+ setClassLoaderCacheEnabled( Boolean.valueOf( this.chainedProperties.getProperty( ClassLoaderCacheOption.PROPERTY_NAME,
+ "true" ) ) );
}
/**
@@ -690,6 +704,16 @@
return this.maxThreads;
}
+ public boolean isClassLoaderCacheEnabled() {
+ return this.classLoaderCacheEnabled;
+ }
+
+ public void setClassLoaderCacheEnabled(final boolean classLoaderCacheEnabled) {
+ checkCanChange(); // throws an exception if a change isn't possible;
+ this.classLoaderCacheEnabled = classLoaderCacheEnabled;
+ this.classLoader.setCachingEnabled( this.classLoaderCacheEnabled );
+ }
+
private void initProcessNodeInstanceFactoryRegistry() {
this.processNodeInstanceFactoryRegistry = new NodeInstanceFactoryRegistry();
@@ -967,7 +991,9 @@
}
public void setClassLoader(ClassLoader classLoader) {
- this.classLoader = ClassLoaderUtil.getClassLoader( classLoader, getClass() );
+ this.classLoader = ClassLoaderUtil.getClassLoader( classLoader,
+ getClass(),
+ isClassLoaderCacheEnabled() );
}
/**
@@ -1223,6 +1249,8 @@
return (T) (this.multithread ? MultithreadEvaluationOption.YES : MultithreadEvaluationOption.NO);
} else if ( MBeansOption.class.equals( option ) ) {
return (T) (this.isMBeansEnabled() ? MBeansOption.ENABLED : MBeansOption.DISABLED);
+ } else if ( ClassLoaderCacheOption.class.equals( option ) ) {
+ return (T) (this.isClassLoaderCacheEnabled() ? ClassLoaderCacheOption.ENABLED : ClassLoaderCacheOption.DISABLED);
}
return null;
@@ -1263,6 +1291,8 @@
setMultithreadEvaluation( ((MultithreadEvaluationOption) option).isMultithreadEvaluation() );
} else if ( option instanceof MBeansOption ) {
setMBeansEnabled( ((MBeansOption) option).isEnabled() );
+ } else if ( option instanceof ClassLoaderCacheOption ) {
+ setClassLoaderCacheEnabled( ((ClassLoaderCacheOption) option).isClassLoaderCacheEnabled() );
}
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SessionConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SessionConfiguration.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SessionConfiguration.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -118,7 +118,9 @@
}
private void init(ClassLoader classLoader, Properties properties) {
- this.classLoader = ClassLoaderUtil.getClassLoader( classLoader, getClass() );
+ this.classLoader = ClassLoaderUtil.getClassLoader( classLoader,
+ getClass(),
+ false );
this.immutable = false;
this.chainedProperties = new ChainedProperties( "session.conf", this.classLoader );
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -32,7 +32,6 @@
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -50,8 +49,8 @@
import org.drools.impl.EnvironmentFactory;
import org.drools.management.DroolsManagementAgent;
import org.drools.process.core.Process;
+import org.drools.rule.DialectRuntimeRegistry;
import org.drools.rule.DroolsCompositeClassLoader;
-import org.drools.rule.DialectRuntimeRegistry;
import org.drools.rule.Function;
import org.drools.rule.ImportDeclaration;
import org.drools.rule.InvalidPatternException;
@@ -59,7 +58,6 @@
import org.drools.rule.Rule;
import org.drools.rule.TypeDeclaration;
import org.drools.spi.FactHandleFactory;
-import org.drools.time.Calendar;
/**
* Implementation of <code>RuleBase</code>.
@@ -87,14 +85,14 @@
private Map agendaGroupRuleTotals;
- private transient DroolsCompositeClassLoader rootClassLoader;
+ private transient DroolsCompositeClassLoader rootClassLoader;
/**
* The fact handle factory.
*/
private FactHandleFactory factHandleFactory;
- private transient Map<String, Class< ? >> globals;
+ private transient Map<String, Class< ? >> globals;
private ReloadPackageCompilationData reloadPackageCompilationData = null;
@@ -153,7 +151,8 @@
this.agendaGroupRuleTotals = new HashMap();
}
- this.rootClassLoader = new DroolsCompositeClassLoader( this.config.getClassLoader() );
+ this.rootClassLoader = new DroolsCompositeClassLoader( this.config.getClassLoader(),
+ this.config.isClassLoaderCacheEnabled() );
this.pkgs = new HashMap<String, Package>();
this.processes = new HashMap();
this.globals = new HashMap<String, Class< ? >>();
@@ -199,6 +198,9 @@
droolsStream = new DroolsObjectOutputStream( bytes );
}
+ // must write this option first in order to properly deserialize later
+ droolsStream.writeBoolean( this.config.isClassLoaderCacheEnabled() );
+
droolsStream.writeObject( this.config );
droolsStream.writeObject( this.pkgs );
@@ -250,7 +252,8 @@
droolsStream = new DroolsObjectInputStream( bytes );
}
- this.rootClassLoader = new DroolsCompositeClassLoader( droolsStream.getParentClassLoader() );
+ boolean classLoaderCacheEnabled = droolsStream.readBoolean();
+ this.rootClassLoader = new DroolsCompositeClassLoader( droolsStream.getParentClassLoader(), classLoaderCacheEnabled );
droolsStream.setClassLoader( this.rootClassLoader );
droolsStream.setRuleBase( this );
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ClassPathResource.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ClassPathResource.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/io/impl/ClassPathResource.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -9,15 +9,12 @@
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Reader;
-import java.net.URI;
-import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import org.drools.core.util.ClassUtils;
import org.drools.core.util.StringUtils;
import org.drools.io.Resource;
import org.drools.io.internal.InternalResource;
@@ -29,16 +26,17 @@
*+
*/
-public class ClassPathResource extends BaseResource
+public class ClassPathResource extends BaseResource
implements
- InternalResource, Externalizable {
+ InternalResource,
+ Externalizable {
private String path;
private ClassLoader classLoader;
- private Class clazz;
+ private Class< ? > clazz;
private long lastRead;
-
+
public ClassPathResource() {
-
+
}
public ClassPathResource(String path) {
@@ -48,7 +46,7 @@
}
public ClassPathResource(String path,
- Class clazz) {
+ Class<?> clazz) {
this( path,
clazz,
null );
@@ -62,16 +60,18 @@
}
public ClassPathResource(String path,
- Class clazz,
+ Class<?> clazz,
ClassLoader classLoader) {
if ( path == null ) {
throw new IllegalArgumentException( "path cannot be null" );
}
this.path = path;
this.clazz = clazz;
- this.classLoader = ClassLoaderUtil.getClassLoader( classLoader, clazz );
+ this.classLoader = ClassLoaderUtil.getClassLoader( classLoader,
+ clazz,
+ false );
}
-
+
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject( this.path );
}
@@ -79,7 +79,7 @@
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
this.path = (String) in.readObject();
- }
+ }
/**
* This implementation opens an InputStream for the given class path resource.
@@ -90,8 +90,8 @@
InputStream is = null;
if ( this.clazz != null ) {
is = this.clazz.getResourceAsStream( this.path );
- }
-
+ }
+
if ( is == null ) {
is = this.classLoader.getResourceAsStream( this.path );
}
@@ -112,8 +112,8 @@
URL url = null;
if ( this.clazz != null ) {
url = this.clazz.getResource( this.path );
- }
-
+ }
+
if ( url == null ) {
url = this.classLoader.getResource( this.path );
}
@@ -146,7 +146,7 @@
public Reader getReader() throws IOException {
return new InputStreamReader( getInputStream() );
}
-
+
public boolean isDirectory() {
try {
URL url = getURL();
@@ -156,7 +156,7 @@
}
File file = new File( StringUtils.toURI( url.toString() ).getSchemeSpecificPart() );
-
+
return file.isDirectory();
} catch ( Exception e ) {
return false;
@@ -167,32 +167,32 @@
try {
URL url = getURL();
- if ( "file".equals( url.getProtocol() ) ) {
+ if ( "file".equals( url.getProtocol() ) ) {
File dir = new File( StringUtils.toURI( url.toString() ).getSchemeSpecificPart() );
-
+
List<Resource> resources = new ArrayList<Resource>();
-
+
for ( File file : dir.listFiles() ) {
resources.add( new FileSystemResource( file ) );
}
-
+
return resources;
}
} catch ( Exception e ) {
// swollow as we'll throw an exception anyway
}
-
+
throw new RuntimeException( "This Resource cannot be listed, or is not a directory" );
- }
+ }
public ClassLoader getClassLoader() {
return this.classLoader;
}
-
- public Class getClazz() {
+
+ public Class<?> getClazz() {
return this.clazz;
}
-
+
public boolean equals(Object object) {
if ( object == null || !(object instanceof ClassPathResource) ) {
return false;
@@ -214,5 +214,4 @@
return "[ClassPathResource path='" + this.path + "']";
}
-
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/DroolsCompositeClassLoader.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/DroolsCompositeClassLoader.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/DroolsCompositeClassLoader.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -12,17 +12,15 @@
public class DroolsCompositeClassLoader extends ClassLoader
implements
DroolsClassLoader {
-
/* Assumption: modifications are really rare, but iterations are frequent. */
private final List<ClassLoader> classLoaders = new CopyOnWriteArrayList<ClassLoader>();
- private boolean hasParent = false;
-
- public DroolsCompositeClassLoader(final ClassLoader parentClassLoader) {
+ private final boolean hasParent;
+
+ public DroolsCompositeClassLoader(final ClassLoader parentClassLoader,
+ final boolean cacheParentCalls) {
super( parentClassLoader );
- if ( parentClassLoader != null ) {
- this.hasParent = true;
- }
+ this.hasParent = parentClassLoader != null;
}
public synchronized void addClassLoader(final ClassLoader classLoader) {
@@ -40,7 +38,6 @@
}
}
this.classLoaders.add( classLoader );
-
}
public synchronized void removeClassLoader(final ClassLoader classLoader) {
@@ -53,9 +50,9 @@
/**
* Search the list of child ClassLoaders
*/
- public Class<?> fastFindClass(final String name) {
+ public Class< ? > fastFindClass(final String name) {
for ( final ClassLoader classLoader : this.classLoaders ) {
- final Class<?> cls = ((DroolsClassLoader) classLoader).fastFindClass( name );
+ final Class< ? > cls = ((DroolsClassLoader) classLoader).fastFindClass( name );
if ( cls != null ) {
return cls;
}
@@ -66,18 +63,19 @@
/**
* This ClassLoader never has classes of it's own, so only search the child ClassLoaders
* and the parent ClassLoader if one is provided
- */
- public Class<?> loadClass(final String name,
- final boolean resolve) throws ClassNotFoundException {
+ */
+ public Class< ? > loadClass(final String name,
+ final boolean resolve) throws ClassNotFoundException {
// search the child ClassLoaders
- Class<?> cls = fastFindClass( name );
-
+ Class< ? > cls;
+ cls = fastFindClass( name );
+
// still not found so search the parent ClassLoader
if ( this.hasParent && cls == null ) {
cls = Class.forName( name,
- true,
- getParent() );
- }
+ true,
+ getParent() );
+ }
if ( resolve ) {
resolveClass( cls );
@@ -89,30 +87,29 @@
/**
* This ClassLoader never has classes of it's own, so only search the child ClassLoaders
* and the parent ClassLoader if one is provided
- */
- public InputStream getResourceAsStream(final String name) {
+ */
+ public InputStream getResourceAsStream(final String name) {
for ( final ClassLoader classLoader : this.classLoaders ) {
InputStream stream = classLoader.getResourceAsStream( name );
if ( stream != null ) {
return stream;
}
}
-
+
if ( this.hasParent ) {
- return getParent().getResourceAsStream( name );
+ return getParent().getResourceAsStream( name );
}
-
+
return null;
}
-
/**
* This ClassLoader never has classes of it's own, so only search the child ClassLoaders
- */
- protected Class<?> findClass(final String name) throws ClassNotFoundException {
- final Class<?> cls = fastFindClass( name );
-
+ */
+ protected Class< ? > findClass(final String name) throws ClassNotFoundException {
+ final Class< ? > cls = fastFindClass( name );
+
if ( cls == null ) {
throw new ClassNotFoundException( name );
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/JavaDialectRuntimeData.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/JavaDialectRuntimeData.java 2010-04-08 20:43:23 UTC (rev 32482)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/JavaDialectRuntimeData.java 2010-04-09 03:08:57 UTC (rev 32483)
@@ -47,23 +47,23 @@
/**
*
*/
- private static final long serialVersionUID = 400L;
+ private static final long serialVersionUID = 400L;
- private static final ProtectionDomain PROTECTION_DOMAIN;
+ private static final ProtectionDomain PROTECTION_DOMAIN;
- private Map invokerLookups;
+ private Map invokerLookups;
- private Map store;
+ private Map store;
- private DialectRuntimeRegistry registry;
+ private DialectRuntimeRegistry registry;
- private transient PackageClassLoader classLoader;
+ private transient PackageClassLoader classLoader;
private transient DroolsCompositeClassLoader rootClassLoader;
- private boolean dirty;
+ private boolean dirty;
- private List<String> wireList = Collections.<String> emptyList();
+ private List<String> wireList = Collections.<String> emptyList();
static {
PROTECTION_DOMAIN = (ProtectionDomain) AccessController.doPrivileged( new PrivilegedAction() {
@@ -129,7 +129,7 @@
this.rootClassLoader );
this.rootClassLoader.addClassLoader( this.classLoader );
}
-
+
public void onRemove() {
this.rootClassLoader.removeClassLoader( this.classLoader );
}
@@ -222,7 +222,7 @@
removeClasses( rule.getLhs() );
// Now remove the rule class - the name is a subset of the consequence name
- String sufix = StringUtils.ucFirst( rule.getConsequence().getName() )+"ConsequenceInvoker";
+ String sufix = StringUtils.ucFirst( rule.getConsequence().getName() ) + "ConsequenceInvoker";
remove( consequenceName.substring( 0,
consequenceName.indexOf( sufix ) ) );
}
@@ -296,7 +296,7 @@
IllegalAccessException {
final Object invoker = getInvokers().get( className );
if ( invoker != null ) {
- wire( className,
+ wire( className,
invoker );
}
}
@@ -383,8 +383,8 @@
throw new RuntimeDroolsException( e );
} catch ( final InstantiationException e ) {
throw new RuntimeDroolsException( e );
- }
-
+ }
+
this.dirty = false;
}
@@ -424,8 +424,13 @@
implements
DroolsClassLoader {
private JavaDialectRuntimeData store;
- DroolsCompositeClassLoader rootClassLoader;
+ DroolsCompositeClassLoader rootClassLoader;
+ private Map<String, Object> cache = new HashMap<String, Object>();
+ private long successfulCalls = 0;
+ private long failedCalls = 0;
+ private long cacheHits = 0;
+
public PackageClassLoader(JavaDialectRuntimeData store,
DroolsCompositeClassLoader rootClassLoader) {
super( rootClassLoader );
@@ -433,16 +438,24 @@
this.store = store;
}
- public Class<?> fastFindClass(final String name) {
- Class<?> cls = findLoadedClass( name );
+ public Class< ? > fastFindClass(final String name) {
+ Class< ? > cls = findLoadedClass( name );
if ( cls == null ) {
final byte[] clazzBytes = this.store.read( convertClassToResourcePath( name ) );
if ( clazzBytes != null ) {
- String pkgName = name.substring(0, name.lastIndexOf('.'));
- if (getPackage(pkgName) == null) {
- definePackage(pkgName, "", "", "", "", "", "", null);
- }
+ String pkgName = name.substring( 0,
+ name.lastIndexOf( '.' ) );
+ if ( getPackage( pkgName ) == null ) {
+ definePackage( pkgName,
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ null );
+ }
cls = defineClass( name,
clazzBytes,
0,
@@ -454,27 +467,45 @@
return cls;
}
- public Class<?> loadClass(final String name,
- final boolean resolve) throws ClassNotFoundException {
- Class<?> cls = fastFindClass( name );
-
- if ( cls == null ) {
- final ClassLoader parent = getParent();
- if ( parent != null ) {
- cls = Class.forName( name,
- true,
- parent );
+ public Class< ? > loadClass(final String name,
+ final boolean resolve) throws ClassNotFoundException {
+ try {
+ if( cache.containsKey( name ) ) {
+ this.cacheHits++;
+ Object result = cache.get( name );
+ if( result instanceof ClassNotFoundException ) {
+ throw (ClassNotFoundException) result;
+ } else {
+ return (Class<?>) result;
+ }
}
+ Class< ? > cls = fastFindClass( name );
+ if ( cls == null ) {
+ final ClassLoader parent = getParent();
+ if ( parent != null ) {
+ cls = Class.forName( name,
+ true,
+ parent );
+ }
+ }
+ if ( resolve && cls != null ) {
+ resolveClass( cls );
+ }
+ if ( cls != null ) {
+ this.successfulCalls++;
+ } else {
+ this.failedCalls++;
+ }
+ cache.put( name, cls );
+ return cls;
+ } catch ( ClassNotFoundException e ) {
+ this.failedCalls++;
+ cache.put( name, e );
+ throw e;
}
-
- if ( resolve && cls != null ) {
- resolveClass( cls );
- }
-
- return cls;
}
- protected Class<?> findClass(final String name) throws ClassNotFoundException {
+ protected Class< ? > findClass(final String name) throws ClassNotFoundException {
return fastFindClass( name );
}
@@ -485,6 +516,16 @@
}
return null;
}
+
+ public void reset() {
+ this.cacheHits = this.failedCalls = this.successfulCalls = 0;
+ this.cache.clear();
+ }
+
+ public void printStats() {
+ System.out.println( "CacheHits = " + this.cacheHits + "\nSuccessful=" + this.successfulCalls + "\nFailed=" + this.failedCalls + "\n" );
+
+ }
}
/**
More information about the jboss-svn-commits
mailing list