[JBoss Microcontainer Development] New message: "Re: AnnotatedElementMetaDataLoader component metadata optimization"
by Kabir Khan
JBoss development,
A new message was posted in the thread "AnnotatedElementMetaDataLoader component metadata optimization":
http://community.jboss.org/message/526634#526634
Author : Kabir Khan
Profile : http://community.jboss.org/people/kabir.khan@jboss.com
Message:
--------------------------------------------------------------
An alternative to changing the tests (although I think we should agree once and for all what the getComponentMetadataRetrieval() should return) is to return a singleton:
public MetaDataRetrieval getComponentMetaDataRetrieval(Signature signature)
{
if (signature == null)
return null;
if (annotated instanceof Class)
{
Class<?> clazz = Class.class.cast(annotated);
if (signature instanceof ConstructorSignature)
{
ConstructorSignature constructorSignature = (ConstructorSignature) signature;
Constructor<?> constructor = constructorSignature.getConstructor();
if (constructor == null)
constructor = SecurityActions.findConstructor(clazz, signature.getParametersTypes(clazz));
if (constructor == null)
{
if (log.isTraceEnabled())
log.trace("Constructor with signature " + signature + " does not exist on class " + clazz.getName());
return null;
}
if (constructor.getAnnotations().length == 0)
return NullAnnotatedElementMetaDataLoader.INSTANCE;
return new AnnotatedElementMetaDataLoader(constructor);
}
//Same for fields, methods, parameters
}
private static class NullAnnotatedElementMetaDataLoader implements MetaDataRetrieval
{
final static NullAnnotatedElementMetaDataLoader INSTANCE = new NullAnnotatedElementMetaDataLoader();
final static ScopeKey NULL_SCOPE_KEY = new ScopeKey(new Scope(CommonLevels.JOINPOINT, INSTANCE));
final static BasicAnnotationsItem NO_ANNOTATIONS_ITEM = new BasicAnnotationsItem(null, new AnnotationItem[0]);
final static BasicMetaDatasItem NO_METADATAS_ITEM = new BasicMetaDatasItem(null, new MetaDataItem[0]);
public MetaDataRetrieval getComponentMetaDataRetrieval(Signature signature)
{
return INSTANCE;
}
public ScopeKey getScope()
{
return NULL_SCOPE_KEY;
}
public MetaDataRetrieval getScopedRetrieval(ScopeLevel level)
{
return INSTANCE;
}
public ValidTime getValidTime()
{
return null;
}
public boolean isEmpty()
{
return true;
}
public <T extends Annotation> AnnotationItem<T> retrieveAnnotation(Class<T> annotationType)
{
return null;
}
public AnnotationsItem retrieveAnnotations()
{
return NO_ANNOTATIONS_ITEM;
}
public AnnotationsItem retrieveAnnotationsAnnotatedWith(Class<? extends Annotation> meta)
{
return NO_ANNOTATIONS_ITEM;
}
public AnnotationsItem retrieveLocalAnnotations()
{
return NO_ANNOTATIONS_ITEM;
}
public MetaDatasItem retrieveLocalMetaData()
{
return NO_METADATAS_ITEM;
}
public MetaDatasItem retrieveMetaData()
{
return NO_METADATAS_ITEM;
}
public <T> MetaDataItem<T> retrieveMetaData(Class<T> type)
{
return null;
}
public MetaDataItem<?> retrieveMetaData(String name)
{
return null;
}
}
I am not sure about the ValidTime, and the ScopeKey seems to not be used, but all tests in mdr pass.
--------------------------------------------------------------
To reply to this message visit the message page: http://community.jboss.org/message/526634#526634
14 years, 3 months
[JBoss Microcontainer Development] New message: "AnnotatedElementMetaDataLoader component metadata optimization"
by Kabir Khan
JBoss development,
A new message was posted in the thread "AnnotatedElementMetaDataLoader component metadata optimization":
http://community.jboss.org/message/526629#526629
Author : Kabir Khan
Profile : http://community.jboss.org/people/kabir.khan@jboss.com
Message:
--------------------------------------------------------------
Inspired by http://community.jboss.org/thread/96937?tstart=0 I did some standalone benchmarks of beans with a lot of methods, and found a bottleneck in CommonAnnotationAdapter which needs to obtain the component metadata for every single constructor/method/property.
The problem is that as far as I can tell:
* MemoryMetaDataLoader delegates to AbstractMutableComponentMetaDataLoader.getComponentMetaDataRetrieval(), which returns null if there is no component metadata:
* public MetaDataRetrieval getComponentMetaDataRetrieval(Signature signature)
{
if (components == null)
return null;
return components.get(signature);
}
* AnnotatedElementMetaDataLoader on the other hand will always return a loader as long as the passed in signature can be found
* public MetaDataRetrieval getComponentMetaDataRetrieval(Signature signature)
{
if (signature == null)
return null;
if (annotated instanceof Class)
{
Class<?> clazz = Class.class.cast(annotated);
if (signature instanceof ConstructorSignature)
{
ConstructorSignature constructorSignature = (ConstructorSignature) signature;
Constructor<?> constructor = constructorSignature.getConstructor();
if (constructor == null)
constructor = SecurityActions.findConstructor(clazz, signature.getParametersTypes(clazz));
if (constructor == null)
{
if (log.isTraceEnabled())
log.trace("Constructor with signature " + signature + " does not exist on class " + clazz.getName());
return null;
}
return new AnnotatedElementMetaDataLoader(constructor);
}
//Same for fields, methods, parameters
The problem with what AnnotatedElementMetaDataLoader does is that even if the constructor in question has no annotations, it still needs to instantiate the "empty" AnnotatedElementMetaDataLoader, which is quite costly. The bulk of that cost goes into creating the ScopeKey, and instantiating ScopeKey's ConcurrentSkipListMap and adding to it take up most of that time.
In an attempt to cut down on this cost I tried the following fix which cuts ~650ms off the AS boot time:
public MetaDataRetrieval getComponentMetaDataRetrieval(Signature signature)
{
if (signature == null)
return null;
if (annotated instanceof Class)
{
Class<?> clazz = Class.class.cast(annotated);
if (signature instanceof ConstructorSignature)
{
ConstructorSignature constructorSignature = (ConstructorSignature) signature;
Constructor<?> constructor = constructorSignature.getConstructor();
if (constructor == null)
constructor = SecurityActions.findConstructor(clazz, signature.getParametersTypes(clazz));
if (constructor == null)
{
if (log.isTraceEnabled())
log.trace("Constructor with signature " + signature + " does not exist on class " + clazz.getName());
return null;
}
//Return null to avoid overhead of initializing AnnotatedElementMetaDataLoader's ScopeKey
//which shows up to be a big bottleneck in AS startup time
if (constructor.getAnnotations().length == 0)
return NullAnnotatedElementMetaDataLoader.INSTANCE;
return new AnnotatedElementMetaDataLoader(constructor);
}
//Same for fields, methods, parameters
The problem with this is that it makes some tests fail in MDR, since they assume that there will always be a ComponentMetaData. Those tests are:
MetaDataAllTestSuite
MetaData Tests
MetaDataLoader Tests
Reflection MetaDataLoader Tests
org.jboss.test.metadata.loader.reflection.test.AnnotatedElementLoaderComponentBasicAnnotationsUnitTestCase
testFieldEmpty(org.jboss.test.metadata.loader.reflection.test.AnnotatedElementLoaderComponentBasicAnnotationsUnitTestCase)
junit.framework.AssertionFailedError: null
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertNotNull(Assert.java:214)
at junit.framework.Assert.assertNotNull(Assert.java:207)
at org.jboss.test.metadata.shared.ComponentBasicAnnotationsTest.testEmpty(ComponentBasicAnnotationsTest.java:102)
at org.jboss.test.metadata.shared.ComponentBasicAnnotationsTest.testFieldEmpty(ComponentBasicAnnotationsTest.java:69)
testConstructorEmpty(org.jboss.test.metadata.loader.reflection.test.AnnotatedElementLoaderComponentBasicAnnotationsUnitTestCase)
junit.framework.AssertionFailedError: null
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertNotNull(Assert.java:214)
at junit.framework.Assert.assertNotNull(Assert.java:207)
at org.jboss.test.metadata.shared.ComponentBasicAnnotationsTest.testEmpty(ComponentBasicAnnotationsTest.java:102)
at org.jboss.test.metadata.shared.ComponentBasicAnnotationsTest.testConstructorEmpty(ComponentBasicAnnotationsTest.java:76)
testMethodEmpty(org.jboss.test.metadata.loader.reflection.test.AnnotatedElementLoaderComponentBasicAnnotationsUnitTestCase)
junit.framework.AssertionFailedError: null
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertNotNull(Assert.java:214)
at junit.framework.Assert.assertNotNull(Assert.java:207)
at org.jboss.test.metadata.shared.ComponentBasicAnnotationsTest.testEmpty(ComponentBasicAnnotationsTest.java:102)
at org.jboss.test.metadata.shared.ComponentBasicAnnotationsTest.testMethodEmpty(ComponentBasicAnnotationsTest.java:83)
testMethodParamsEmpty(org.jboss.test.metadata.loader.reflection.test.AnnotatedElementLoaderComponentBasicAnnotationsUnitTestCase)
junit.framework.AssertionFailedError: null
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertNotNull(Assert.java:214)
at junit.framework.Assert.assertNotNull(Assert.java:207)
at org.jboss.test.metadata.shared.ComponentBasicAnnotationsTest.testEmpty(ComponentBasicAnnotationsTest.java:102)
at org.jboss.test.metadata.shared.ComponentBasicAnnotationsTest.testMethodParamsEmpty(ComponentBasicAnnotationsTest.java:90)
testConstructorParamsEmpty(org.jboss.test.metadata.loader.reflection.test.AnnotatedElementLoaderComponentBasicAnnotationsUnitTestCase)
junit.framework.AssertionFailedError: null
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertNotNull(Assert.java:214)
at junit.framework.Assert.assertNotNull(Assert.java:207)
at org.jboss.test.metadata.shared.ComponentBasicAnnotationsTest.testEmpty(ComponentBasicAnnotationsTest.java:102)
at org.jboss.test.metadata.shared.ComponentBasicAnnotationsTest.testConstructorParamsEmpty(ComponentBasicAnnotationsTest.java:97)
org.jboss.test.metadata.loader.reflection.test.AnnotatedElementLoaderNotPublicUnitTestCase
testSameName(org.jboss.test.metadata.loader.reflection.test.AnnotatedElementLoaderNotPublicUnitTestCase)
junit.framework.AssertionFailedError: null
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertNotNull(Assert.java:214)
at junit.framework.Assert.assertNotNull(Assert.java:207)
at org.jboss.test.metadata.AbstractMetaDataTest.assertNoAnnotation(AbstractMetaDataTest.java:226)
at org.jboss.test.metadata.loader.reflection.test.AnnotatedElementLoaderNotPublicUnitTestCase.testSameName(AnnotatedElementLoaderNotPublicUnitTestCase.java:94)
-------------------
The question is do I "fix" those tests or not? ComponentBasicAnnotationsTest comes in two varieties, both of which run this test:
public void testFieldEmpty() throws Exception
{
MetaData metaData = setupField();
metaData = metaData.getComponentMetaData(new FieldSignature("empty"));
testEmpty(metaData);
}
* AnnotatedElementLoaderComponentBasicAnnotationsUnitTestCase which sets up the field "empty" as follows (FieldBean.empty has no annotations)
protected MetaData setupField()
{
AnnotatedElementMetaDataLoader loader = new AnnotatedElementMetaDataLoader(FieldBean.class);
return new MetaDataRetrievalToMetaDataBridge(loader);
}
*
MemoryLoaderComponentBasicAnnotationsUnitTestCase which sets up the "empty" field like this, which makes sure that there is a componentmetadata for it
protected MetaData setupField()
{
MemoryMetaDataLoader loader = new MemoryMetaDataLoader();
MemoryMetaDataLoader component = new MemoryMetaDataLoader();
loader.addComponentMetaDataRetrieval(new FieldSignature("empty"), component);
//Some more component MetaDataLoaders set up to test other "fields"
...
return new MetaDataRetrievalToMetaDataBridge(loader);
}
We're clearly not counting on there always being a metadata. In practice if there is no component metadata for a particular signature, MetaDataLoader will return null while AnnotatedElementLoader will not, meaning we have two different behaviours for the implemented interface. On the other hand, in the real world (read AS kernel) with things as they have been the component metadata returned to the user will never be null since there would always at least be a created component AnnotatedElementMetaDataLoader there regardless of if all the component MemoryMetaDataLoaders were null or not.
--------------------------------------------------------------
To reply to this message visit the message page: http://community.jboss.org/message/526629#526629
14 years, 3 months
[JBoss Build System Development] New message: "Re: AS build - Overriding the versions in component-matrix/pom.xml through version ranges"
by jaikiran pai
JBoss development,
A new message was posted in the thread "AS build - Overriding the versions in component-matrix/pom.xml through version ranges":
http://community.jboss.org/message/526624#526624
Author : jaikiran pai
Profile : http://community.jboss.org/people/jaikiran
Message:
--------------------------------------------------------------
> pgier wrote:
>
> Can you try just echoing one of the properties that you are passing?
>
>
Since i suspect that it's the maven:dependencies in the "init-dependencies" target of build/build.xml, i added a echo statement to print one of the system properties being passed before the call to maven:dependencies. I then added one more echo statement after the maven:dependencies to print out the resolved version numbers (stored in the pom.dependencies.versions property):
Index: build.xml
===================================================================
--- build.xml (revision 101012)
+++ build.xml (working copy)
@@ -40,7 +40,7 @@
<!-- Set a default file to use to define the thirdparty dependencies. -->
<property name="dist.pom.file" location="pom.xml"/>
-
+ <echo>Property passed from command line ${version.org.jboss.ejb3}</echo>
<!--
- Initialize properties for each dependency in the thirdparty pom
- The properties take the form "groupId:artifactId:packaging"
@@ -51,6 +51,7 @@
scopes="compile, runtime">
<pom refid="pom.project"/>
</maven:dependencies>
+ <echo>versions are: ${pom.dependencies.versions}</echo>
<mapper id="remove-versions" classpathref="maven-ant-tasks.classpath"
classname="org.apache.maven.artifact.ant.VersionMapper"
I then ran mvn clean install from AS-trunk/build folder with the following properties (In this example the property -Dversion.org.jboss.ejb3 in that command line is the one that we are interested in):
mvn clean install -Dskip-download-sources -Dversion.org.jboss.ejb3=\(,1.0] -Dversion.org.jboss.ejb3.common.client=[0,\)
-Dversion.org.jboss.ejb3.core.client=[0,\) -Dversion.org.jboss.ejb3.proxy.client=[0,\)
-Dversion.org.jboss.ejb3.proxy.clustered.client=[0,\)
-Dversion.org.jboss.ejb3.security.client=[0,\) -Dversion.org.jboss.ejb3.jpa.int=[0,\)
-Dversion.org.jboss.metadata.ejb=[0,\)
So i am passing -Dversion.org.jboss.ejb3=\(,1.0] (i.e. version <=1.0). The version specified in component-matrix/pom.xml for this artifact is 1.0.4. After running the command, here's the output:
init-dependencies:
[echo] Property passed from command line (,1.0]
[echo] versions are: 2.0.0-alpha-10:1.0.0-Beta-1:1.5.0.GA:6.0.0-20100216.180345-703:
6.0.0-20100216.180345-702:2.1.1.GA:3.0.1-native-2.0.4.GA:1.0.0.GA:
1.8.0:3.11.0.GA:3.0.0.GA:1.0-alpha-1:1.0:6.0.0-20100216.180345-705:1.0.0-CR-1:1.3:1.2:
6.0.0-20100216.180345-708:1.2.14:1.1:1.0_02.CR2:2.0.1:2.0.0:2.0.2-FCS:2.1.1.SP1:3.2.0.Beta1:
2.7.0.patch02-brew:1:2.0.0.CR3:1.1b:1.1.0.GA_SP1:1.0.0.Alpha1:1.0.0.Alpha2:3.2.1.GA:
6.0.0-20100216.180345-725:1.3.0:6.0.0-20100216.180345-723:6.0.0-20100216.180345-721:1.0.12-brew:
1.2.0.GA:0.3.4:3.0.0.GA_SP1:1.4.0.Beta1:6.0.0-Alpha8:1.0.0.CR7:5.2.0.Beta1:5.0.4.GA:
1.0.0.CR2:1.8.0.8-brew:1.0.0.CR3:3.1.0.GA:1.1.0:1.4.6.GA:1.1.1:2.2.17.GA:
1.0.3.GA:6.0.0-20100216.180345-713:0.1.0:1.0.2.GA:2.0.5.CR1:0.1.4:1.0.0.CR16:
1.1.0.GA:3.3.0.Beta3:3.3.0.Beta2:1.7.1:6.0.0-20100216.180345-715:1.5.2:2.1.2.GA:1.1-brew:
2.6.13.GA:6.0.0-20100216.180345-743:2.5-20081211:6.0.0-20100216.180345-740:2.5.6:6.0.0.Beta6:
6.0.0-20100216.180345-746:1.21-brew:1.5.6:6.0.0.Beta5:6.0.0-20100216.180345-749:
6.0.0-20100216.180345-748:3.0.0-beta-2:2.0.0.GA:1.1.0.Beta1:2.1.1:3.5.0-CR-1:2.1.3:2.1.8.GA:2.2.0.CR1:
4.0.2.GA:2.0-b01:5.0.3.GA:2.0.0.Alpha:2.0.0.Alpha13:6.1.16:6.0.0-20100216.180345-738:4.9.0.GA:2.5.2.SP2:
1.1.0.jboss:2.0.3.SP1:20050927:2.9.1:1.0-RC2:2.2.0.Alpha2:2.2.0.Alpha1:2.1.0.20091223:2.2.0.Alpha6:0.9RC4:
1.3.4-jboss-update1:2.0.0-alpha-1:3.2.3:2.0.0-alpha-4:0.1.0-alpha-2:2.0.0-alpha-3:3.2.6:2.0.0-alpha-2:2.1.0.CR1:
1.0.1.GA:2.0.0-alpha-6:3.0.4.GA:2.0.0.Alpha2:6.0.0-20100216.180345-381:1.4jboss:1.6.1:
1.0.4-20100215.041517-66:3.1:6.0.0-20100216.180345-750:1.0.2:1.0.1:5.1.0.CR1:5.1:1.0.0:1.0-MR1:
1.0.6:1.3.0.Beta2:1.0.4:2.7.6-brew:1.0.3:2.0.2.Beta3:2.2:1.0.0-alpha-4:1.2.2:1.2.8:1.4.3:2.4.0:
1.1.1.GA:2.3.1jboss.patch01-brew:1.4.2
The first echo statement output shows that the property is being correctly passed. The second echo statement output (after maven:dependencies) shows that the version is being resolved to 1.0.4 (i.e. the one specified in component-matrix). Search for the string ":1.0.4:" in that echo statement output. So looks like the version range is completely ignored
For the sake of testing, i then passed an explicit version override of 1.0.3 (i.e. not a version range) from the command line:
mvn clean install -Dskip-download-sources -Dversion.org.jboss.ejb3=1.0.3 -Dversion.org.jboss.ejb3.common.client=[0,\)
-Dversion.org.jboss.ejb3.core.client=[0,\) -Dversion.org.jboss.ejb3.proxy.client=[0,\)
-Dversion.org.jboss.ejb3.proxy.clustered.client=[0,\)
-Dversion.org.jboss.ejb3.security.client=[0,\) -Dversion.org.jboss.ejb3.jpa.int=[0,\)
-Dversion.org.jboss.metadata.ejb=[0,\)
And here's the output:
init-dependencies:
[echo] Property passed from command line 1.0.3
[echo] versions are: 2.0.0-alpha-10:1.0.0-Beta-1:1.5.0.GA:6.0.0-20100216.180345-703:6.0.0-20100216.180345-702:
2.1.1.GA:3.0.1-native-2.0.4.GA:1.0.0.GA:1.8.0:3.11.0.GA:3.0.0.GA:1.0-alpha-1:1.0:6.0.0-20100216.180345-705:
1.0.0-CR-1:1.3:1.2:6.0.0-20100216.180345-708:1.2.14:1.1:1.0_02.CR2:2.0.1:2.0.0:2.0.2-FCS:2.1.1.SP1:
3.2.0.Beta1:2.7.0.patch02-brew:1:2.0.0.CR3:1.1b:1.1.0.GA_SP1:1.0.0.Alpha1:1.0.0.Alpha2:3.2.1.GA:
6.0.0-20100216.180345-725:1.3.0:6.0.0-20100216.180345-723:6.0.0-20100216.180345-721:1.0.12-brew:1.2.0.GA:
0.3.4:3.0.0.GA_SP1:1.4.0.Beta1:6.0.0-Alpha8:1.0.0.CR7:5.2.0.Beta1:5.0.4.GA:1.0.0.CR2:1.8.0.8-brew:
1.0.0.CR3:3.1.0.GA:1.1.0:1.4.6.GA:1.1.1:2.2.17.GA:1.0.3.GA:6.0.0-20100216.180345-713:0.1.0:
1.0.2.GA:2.0.5.CR1:0.1.4:1.0.0.CR16:1.1.0.GA:3.3.0.Beta3:3.3.0.Beta2:1.7.1:6.0.0-20100216.180345-715:
1.5.2:2.1.2.GA:1.1-brew:2.6.13.GA:6.0.0-20100216.180345-743:2.5-20081211:6.0.0-20100216.180345-740:2.5.6:
6.0.0.Beta6:6.0.0-20100216.180345-746:1.21-brew:1.5.6:6.0.0.Beta5:6.0.0-20100216.180345-749:
6.0.0-20100216.180345-748:3.0.0-beta-2:2.0.0.GA:1.1.0.Beta1:2.1.1:3.5.0-CR-1:2.1.3:2.1.8.GA:
2.2.0.CR1:4.0.2.GA:2.0-b01:5.0.3.GA:2.0.0.Alpha:2.0.0.Alpha13:6.1.16:6.0.0-20100216.180345-738:
4.9.0.GA:2.5.2.SP2:1.1.0.jboss:2.0.3.SP1:20050927:2.9.1:1.0-RC2:2.2.0.Alpha2:2.2.0.Alpha1:
2.1.0.20091223:2.2.0.Alpha6:0.9RC4:1.3.4-jboss-update1:2.0.0-alpha-1:3.2.3:2.0.0-alpha-4:0.1.0-alpha-2:
2.0.0-alpha-3:3.2.6:2.0.0-alpha-2:2.1.0.CR1:1.0.1.GA:2.0.0-alpha-6:3.0.4.GA:2.0.0.Alpha2:
6.0.0-20100216.180345-381:1.4jboss:1.6.1:1.0.4-20100215.041517-66:3.1:6.0.0-20100216.180345-750:
1.0.2:1.0.1:5.1.0.CR1:5.1:1.0.0:1.0-MR1:1.0.6:1.3.0.Beta2:2.7.6-brew:1.0.3:2.0.2.Beta3:2.2:
1.0.0-alpha-4:1.2.1:1.2.2:1.2.8:1.4.3:2.4.0:1.1.1.GA:2.3.1jboss.patch01-brew:1.4.2
The echo statement after the maven:dependencies, shows that it picked up the version override and resolved the version to 1.0.3 (search for ":1.0.3:") instead of the one specified in component-matrix/pom.xml.
So this appears to be something around the maven:dependencies and it's version range resolution.
--------------------------------------------------------------
To reply to this message visit the message page: http://community.jboss.org/message/526624#526624
14 years, 3 months