[jboss-svn-commits] JBL Code SVN: r36542 - labs/jbossrules/soa_branches/BRMS-5.0.2-GA_BRMS-532/drools-core/src/main/java/org/drools/base.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sun Jan 16 21:54:04 EST 2011
Author: tsurdilovic
Date: 2011-01-16 21:54:04 -0500 (Sun, 16 Jan 2011)
New Revision: 36542
Modified:
labs/jbossrules/soa_branches/BRMS-5.0.2-GA_BRMS-532/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java
Log:
BRMS-532 Drools Session insert ConcurrentModificationException in Multithreading Environment
Modified: labs/jbossrules/soa_branches/BRMS-5.0.2-GA_BRMS-532/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java
===================================================================
--- labs/jbossrules/soa_branches/BRMS-5.0.2-GA_BRMS-532/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java 2011-01-17 02:53:34 UTC (rev 36541)
+++ labs/jbossrules/soa_branches/BRMS-5.0.2-GA_BRMS-532/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java 2011-01-17 02:54:04 UTC (rev 36542)
@@ -1,19 +1,3 @@
-/**
- * Copyright 2010 JBoss Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
package org.drools.base;
import java.security.ProtectionDomain;
@@ -24,20 +8,55 @@
import java.util.concurrent.ConcurrentMap;
import org.drools.RuntimeDroolsException;
-import org.drools.core.util.asm.ClassFieldInspector;
+import org.drools.util.asm.ClassFieldInspector;
public class ClassFieldAccessorCache {
+ private static ClassFieldAccessorCache instance;
- private Map<ClassLoader, CacheEntry> cacheByClassLoader;
+ private Map<ClassLoader, CacheEntry> cacheByClassLoader;
- private ClassLoader classLoader;
+ private ClassLoader classLoader;
+ // private boolean eagerWire;
+
+ // public static ClassFieldAccessorCache getInstance() {
+ // if ( instance == null ) {
+ // ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ // if ( cl == null ) {
+ // cl = ClassFieldAccessorCache.class.getClassLoader();
+ // }
+ // instance = new ClassFieldAccessorCache( cl );
+ // }
+ //
+ // return instance;
+ // }
+ //
+ // public ClassFieldAccessorCache() {
+ // // we don't set the classloader here, its just for Externalisable
+ // // any using class will need to set the classloader before using
+ // this( null );
+ // }
+
public ClassFieldAccessorCache(ClassLoader classLoader) {
// lookup = new HashMap<AccessorKey, LookupEntry>();
cacheByClassLoader = new WeakHashMap<ClassLoader, CacheEntry>();
this.classLoader = classLoader;
}
+ // public void writeExternal(ObjectOutput out) throws IOException {
+ // out.writeObject( lookup );
+ //
+ // }
+ //
+ // public void readExternal(ObjectInput in) throws IOException,
+ // ClassNotFoundException {
+ // lookup = ( Map<AccessorKey, LookupEntry> ) in.readObject();
+ // }
+
+ public void setClassLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
public ClassLoader getClassLoader() {
return this.classLoader;
}
@@ -46,24 +65,20 @@
// always lookup the class, as the ClassObjectType might refer to the class from another ClassLoader
Class cls = getClass( objectType.getClassName() );
CacheEntry cache = getCacheEntry( cls );
- return cache.getClassObjectType( cls,
- objectType );
+ return cache.getClassObjectType( cls, objectType );
}
-
+
public static class ClassObjectTypeKey {
- private Class cls;
+ private Class cls;
private boolean event;
-
public ClassObjectTypeKey(Class cls,
boolean event) {
this.cls = cls;
this.event = event;
}
-
public Class getCls() {
return cls;
}
-
public boolean isEvent() {
return event;
}
@@ -88,6 +103,8 @@
return true;
}
+
+
}
public BaseClassFieldReader getReadAcessor(ClassFieldReader reader) {
@@ -107,37 +124,40 @@
public BaseClassFieldWriter getWriteAcessor(ClassFieldWriter writer) {
String className = writer.getClassName();
String fieldName = writer.getFieldName();
-
+
Class cls = getClass( className );
CacheEntry cache = getCacheEntry( cls );
-
+
// get the ReaderAccessor for this key
return cache.getWriteAccessor( new AccessorKey( className,
fieldName,
AccessorKey.AccessorType.FieldAccessor ),
cls );
}
-
- public Class getClass(String className) {
+
+ public Class getClass(String className) {
try {
return this.classLoader.loadClass( className );
} catch ( ClassNotFoundException e ) {
throw new RuntimeDroolsException( "Unable to resolve class '" + className + "'" );
}
- }
-
+ }
+
public CacheEntry getCacheEntry(Class cls) {
// System classloader classes return null on some JVMs
- ClassLoader cl = cls.getClassLoader() != null ? cls.getClassLoader() : this.classLoader;
+ ClassLoader cl = cls.getClassLoader() != null ?
+ cls.getClassLoader() : ( this.classLoader != null ) ?
+ this.classLoader :
+ ClassLoader.getSystemClassLoader();
CacheEntry cache = this.cacheByClassLoader.get( cl );
if ( cache == null ) {
// setup a cache for this ClassLoader
- cache = new CacheEntry( this.classLoader );
+ cache = new CacheEntry( cl );
this.cacheByClassLoader.put( cl,
cache );
}
-
+
return cache;
}
@@ -156,7 +176,7 @@
}
this.byteArrayClassLoader = new ByteArrayClassLoader( parentClassLoader );
}
-
+
public ByteArrayClassLoader getByteArrayClassLoader() {
return byteArrayClassLoader;
}
@@ -169,11 +189,11 @@
key.getFieldName(),
this );
BaseClassFieldReader existingReader = this.readCache.putIfAbsent( key,
- reader );
- if ( existingReader != null ) {
- // Raced, use the (now) existing entry
- reader = existingReader;
- }
+ reader );
+ if ( existingReader != null ) {
+ // Raced, use the (now) existing entry
+ reader = existingReader;
+ }
}
return reader;
@@ -183,15 +203,15 @@
Class cls) {
BaseClassFieldWriter writer = this.writeCache.get( key );
if ( writer == null ) {
- writer = ClassFieldAccessorFactory.getInstance().getClassFieldWriter( cls,
+ writer = ClassFieldAccessorFactory.getInstance().getClassFieldWriter( cls,
key.getFieldName(),
this );
- BaseClassFieldWriter existingWriter = this.writeCache.putIfAbsent( key,
- writer );
- if ( existingWriter != null ) {
+ BaseClassFieldWriter existingWriter = this.writeCache.putIfAbsent( key,
+ writer );
+ if ( existingWriter != null ) {
// Raced, use the (now) existing entry
writer = existingWriter;
- }
+ }
}
return writer;
@@ -200,13 +220,13 @@
public Map<Class< ? >, ClassFieldInspector> getInspectors() {
return inspectors;
}
-
+
public ClassObjectType getClassObjectType(Class<?> cls,
- ClassObjectType objectType) {
- ClassObjectTypeKey key = new ClassObjectTypeKey( cls,
- objectType.isEvent() );
+ ClassObjectType objectType) {
+ ClassObjectTypeKey key = new ClassObjectTypeKey( cls,
+ objectType.isEvent() );
ClassObjectType existing = objectTypes.get( key );
-
+
if ( existing == null ) {
objectType.setClassType( cls ); // most likely set, but set anyway.
existing = objectTypes.putIfAbsent( key, objectType );
@@ -215,8 +235,8 @@
existing = objectType;
}
}
-
- return existing;
+
+ return existing;
}
}
@@ -238,3 +258,4 @@
}
}
+
More information about the jboss-svn-commits
mailing list