|
Home > Archive > Apache JDO Project > September 2005 > status update: ri11 enhancer support for jdk 1.5
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
status update: ri11 enhancer support for jdk 1.5
|
|
| Martin Zaun 2005-09-16, 5:45 pm |
|
Hi Craig,
here's the current status of testing my RI11 enhancer changes for
Java 5 support (running jdk 1.5.0_05):
maven.compile.source = 1.3 1.3 1.5
maven.compile.target = 1.3 1.5 1.5
-------------------------------------------------------------------
tck11 OK OK OK
junit tests (maven build) OK OK 2 errors
runtest.list/security OK OK 1+5 errors
multiJVMtests error error error
ClassNotFoundException: com.sun.jndi.fscontext.RefFSContextFactory
So, the basic 1.5 classfile support seems to be working (target=1.5),
but there are errors when compiling the ri11 and junit tests with
source=1.5, into which I started looking.
More details on the errors below.
Martin
----------------------------------------------------------------------
Failing JUnit tests:
[junit] [ERROR] TEST org.apache.jdo.test.Test_JDOModel FAILED
[junit] [ERROR] TEST org.apache.jdo.test.Test_Query FAILED
How can I get more information on these failures?
I tried modifying the log level in ri11/test/conf/
logging.properties and simplelog.properties
but with no success.
----------------------------------------------------------------------
JDO RI test suite, runtest.list and runtest.security:
Tests run: 149, Failures: 1, Errors: 5
Details below.
----------------------------------------------------------------------
[java] RUN Test_JDOModel.testDefaults FAILURE
[java] There was 1 failure:
[java] 1) testDefaults(org.apache.jdo.test.Test_JDOModel)junit.framework.Com
parisonFailure: Wrong list of persistentSerializableFieldNumbers of class org.ap
ache.jdo.pc.empdept.PCFullTimeEmployee expected:<..., 10...> but was:<......>
[java] at org.apache.jdo.test.Test_JDOModel.verifyPCFullTimeEmployee(Te
st_JDOModel.java:304)
....
[java] Caused by: java.util.MissingResourceException: Can't find resource fo
r bundle java.util.PropertyResourceBundle, key ERR_MultipleJavaField
----------------------------------------------------------------------
[java] RUN Test_EmpDeptSerialization.test ERROR
[java] 1) test(org.apache.jdo.test.Test_EmpDeptSerialization)java.lang.Excep
tionInInitializerError
[java] at org.apache.jdo.test.Test_EmpDeptSerialization.createObjects(T
est_EmpDeptSerialization.java:105)
----------------------------------------------------------------------
[java] RUN Test_Inheritance.test ERROR
[java] 2) test(org.apache.jdo.test.Test_Inheritance)java.lang.NoClassDefFoun
dError
[java] at org.apache.jdo.test.EmpDeptSupport.createObjects(EmpDeptSuppo
rt.java:76)
----------------------------------------------------------------------
[java] RUN Test_StringOID.test ERROR
[java] 3) test(org.apache.jdo.test.Test_StringOID)java.lang.NoClassDefFoundE
rror
[java] at org.apache.jdo.test.EmpDeptSupport.createObjects(EmpDeptSuppo
rt.java:76)
----------------------------------------------------------------------
[java] RUN Test_Query.testMemoryQueries ERROR
[java] 4) testMemoryQueries(org.apache.jdo.test.Test_Query)java.lang.Excepti
onInInitializerError
[java] at org.apache.jdo.test.Test_Query.createObjects(Test_Query.java:
344)
....
[java] Caused by: java.util.MissingResourceException: Can't find resource fo
r bundle java.util.PropertyResourceBundle, key ERR_MultipleJavaField
----------------------------------------------------------------------
[java] RUN Test_Query.testExtentQueries ERROR
[java] 5) testExtentQueries(org.apache.jdo.test.Test_Query)java.lang.NoClass
DefFoundError
[java] at org.apache.jdo.test.Test_Query.createObjects(Test_Query.java:
344)
----------------------------------------------------------------------
JDO RI test suite, runtest.multiJVMtests:
2 errors, even with maven.compile.source,target = 1.3
[java] RUN Test_FetchInserted.test ERROR
[java] 1) test(org.apache.jdo.test.Test_FetchInserted)javax.naming.NoInitial
ContextException: Cannot instantiate class: com.sun.jndi.fscontext.RefFSContextF
actory [Root exception is java.lang.ClassNotFoundException: com.sun.jndi.fsconte
xt.RefFSContextFactory]
This sun-specific JDK class seems to be missing or renamed in
JDK 1.5. I guess we only have to change the entry in
ri11/test/conf/jndi.properties. If anyone knows, let me know.
----------------------------------------------------------------------
| |
| Michael Bouschen 2005-09-16, 5:45 pm |
| Hi Martin,
some remarks:
- About the ClassNotFoundException ...RefFSContextFactory:
You need to copy the jndi jars fscontext.jar and providerutil.jar to
trunk/lib/ext. The issue is that we cannot download the jndi jars
automatically, because you need to accept the license agreement. Have a
look at trunk/README.txt, section "JNDI implementation".
There is no need to change the jndi property in project.properties.
- Maven calls the junit tests as part of the build goal in the ri11
project. The test output is stored under target/test-results with a log
file per test class.
- I'm surprised about the MissingResourceException for the key
ERR_MultipleJavaField. Is there any difference in the bundle lookup in
Java 5?
I hope this helps.
Regards Michael
>
> Hi Craig,
>
> here's the current status of testing my RI11 enhancer changes for
> Java 5 support (running jdk 1.5.0_05):
>
> maven.compile.source = 1.3 1.3 1.5
> maven.compile.target = 1.3 1.5 1.5
> -------------------------------------------------------------------
> tck11 OK OK OK
> junit tests (maven build) OK OK 2 errors
> runtest.list/security OK OK 1+5 errors
> multiJVMtests error error error
> ClassNotFoundException: com.sun.jndi.fscontext.RefFSContextFactory
>
> So, the basic 1.5 classfile support seems to be working (target=1.5),
> but there are errors when compiling the ri11 and junit tests with
> source=1.5, into which I started looking.
>
> More details on the errors below.
>
> Martin
>
> ----------------------------------------------------------------------
>
> Failing JUnit tests:
>
> [junit] [ERROR] TEST org.apache.jdo.test.Test_JDOModel FAILED
> [junit] [ERROR] TEST org.apache.jdo.test.Test_Query FAILED
>
> How can I get more information on these failures?
>
> I tried modifying the log level in ri11/test/conf/
> logging.properties and simplelog.properties
> but with no success.
>
> ----------------------------------------------------------------------
>
> JDO RI test suite, runtest.list and runtest.security:
>
> Tests run: 149, Failures: 1, Errors: 5
>
> Details below.
>
> ----------------------------------------------------------------------
>
> [java] RUN Test_JDOModel.testDefaults FAILURE
>
> [java] There was 1 failure:
> [java] 1)
> testDefaults(org.apache.jdo.test.Test_JDOModel)junit.framework.Com
> parisonFailure: Wrong list of persistentSerializableFieldNumbers of
> class org.ap
> ache.jdo.pc.empdept.PCFullTimeEmployee expected:<..., 10...> but
> was:<......>
> [java] at
> org.apache.jdo.test.Test_JDOModel.verifyPCFullTimeEmployee(Te
> st_JDOModel.java:304)
> ...
> [java] Caused by: java.util.MissingResourceException: Can't find
> resource fo
> r bundle java.util.PropertyResourceBundle, key ERR_MultipleJavaField
>
> ----------------------------------------------------------------------
>
> [java] RUN Test_EmpDeptSerialization.test ERROR
>
> [java] 1)
> test(org.apache.jdo.test.Test_EmpDeptSerialization)java.lang.Excep
> tionInInitializerError
> [java] at
> org.apache.jdo.test.Test_EmpDeptSerialization.createObjects(T
> est_EmpDeptSerialization.java:105)
>
> ----------------------------------------------------------------------
>
> [java] RUN Test_Inheritance.test ERROR
>
> [java] 2)
> test(org.apache.jdo.test.Test_Inheritance)java.lang.NoClassDefFoun
> dError
> [java] at
> org.apache.jdo.test.EmpDeptSupport.createObjects(EmpDeptSuppo
> rt.java:76)
>
> ----------------------------------------------------------------------
>
> [java] RUN Test_StringOID.test ERROR
>
> [java] 3)
> test(org.apache.jdo.test.Test_StringOID)java.lang.NoClassDefFoundE
> rror
> [java] at
> org.apache.jdo.test.EmpDeptSupport.createObjects(EmpDeptSuppo
> rt.java:76)
>
> ----------------------------------------------------------------------
>
> [java] RUN Test_Query.testMemoryQueries ERROR
>
> [java] 4)
> testMemoryQueries(org.apache.jdo.test.Test_Query)java.lang.Excepti
> onInInitializerError
> [java] at
> org.apache.jdo.test.Test_Query.createObjects(Test_Query.java:
> 344)
> ...
> [java] Caused by: java.util.MissingResourceException: Can't find
> resource fo
> r bundle java.util.PropertyResourceBundle, key ERR_MultipleJavaField
>
> ----------------------------------------------------------------------
>
> [java] RUN Test_Query.testExtentQueries ERROR
>
> [java] 5)
> testExtentQueries(org.apache.jdo.test.Test_Query)java.lang.NoClass
> DefFoundError
> [java] at
> org.apache.jdo.test.Test_Query.createObjects(Test_Query.java:
> 344)
>
> ----------------------------------------------------------------------
>
> JDO RI test suite, runtest.multiJVMtests:
>
> 2 errors, even with maven.compile.source,target = 1.3
>
> [java] RUN Test_FetchInserted.test ERROR
>
> [java] 1)
> test(org.apache.jdo.test.Test_FetchInserted)javax.naming.NoInitial
> ContextException: Cannot instantiate class:
> com.sun.jndi.fscontext.RefFSContextF
> actory [Root exception is java.lang.ClassNotFoundException:
> com.sun.jndi.fsconte
> xt.RefFSContextFactory]
>
>
> This sun-specific JDK class seems to be missing or renamed in
> JDK 1.5. I guess we only have to change the entry in
> ri11/test/conf/jndi.properties. If anyone knows, let me know.
>
> ----------------------------------------------------------------------
--
Michael Bouschen Tech@Spree Engineering GmbH
mailto:mbo.tech@spree.de http://www.tech.spree.de/
Tel.:++49/30/235 520-33 Buelowstr. 66
Fax.:++49/30/2175 2012 D-10783 Berlin
| |
| Martin Zaun 2005-09-22, 8:45 pm |
|
Michael, Craig,
A status update on the RI11 enhancer changes for Java 5 support:
As it looks like, the junit test errors are not caused by the
enhancer changes but by order-of-class-loading issues with the
tests or model/query, which just haven't been exposed before.
I still don't have the all the pieces, but here are some facts:
- The junit tests errors occur when compiling with source=1.5,
while source=1.4 and target=1.5 runs fine.
- I've compared the disassembled, enhanced classes obtained by
source=1.5 against 1.4: They're practically equivalent. (One
difference, though, is the use of the unsynchronized class
StringBuilder instead of StringBuffer).
- The root cause for Test_Query to fail with source=1.5 is a
ModelFatalException("ERR_MultipleJavaField"). (Actually, this
exception is preempted by a MissingResourceException).
This happens during registration of class Department, when the
JavaModel complains that the field 'deptid' has already been
registered. The line numbers might be inacurate due to added
printlns:
at org.apache.jdo.impl.model.java.reflection.ReflectionJavaType.createJavaField(ReflectionJavaType.java:206)
at org.apache.jdo.impl.model.java.runtime.RegisterClassListener.updateJDOField(RegisterClassListener.java:173)
at org.apache.jdo.impl.model.java.runtime.RegisterClassListener.updateJDOClass(RegisterClassListener.java:154)
at org.apache.jdo.impl.model.java.runtime.RegisterClassListener.registerClass(RegisterClassListener.java:83)
at javax.jdo.spi.JDOImplHelper.registerClass(JDOImplHelper.java:288)
at org.apache.jdo.pc.xempdept.Department.<clinit>(Department.java)
- Turns out that with source=1.5, it turns out that the 'deptid'
field has been registred before with the model during a
query.compile():
at org.apache.jdo.impl.model.java.reflection.ReflectionJavaType.getDeclaredJavaField(ReflectionJavaType.java:241)
at org.apache.jdo.impl.model.java.reflection.ReflectionJavaType.getJavaField(ReflectionJavaType.java:177)
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.analyseDefinedIdentifier(Semantic.java:306)
...
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.query(Semantic.java:1077)
at org.apache.jdo.impl.jdoql.jdoqlc.JDOQLC.semanticCheck(JDOQLC.java:261)
at org.apache.jdo.impl.jdoql.QueryImpl.compile(QueryImpl.java:454)
...
at org.apache.jdo.test.Test_Query.runQueryTestSuite(Test_Query.java:198)
- For a test, I changed ReflectionJavaType.getDeclaredJavaField()
not to store the JavaField field in the private HashMap
'javaFields', and Test_Query runs fine then. But this doesn't
look like the right approach to me.
- Checking the point of time when PC classes register with the
runtime, it's different with source=1.5 versus 1.4!
Here's the order with source=1.5, marking when 'deptid' get's
inserted for the first time:
+++ jdoClass.getName() = org.apache.jdo.pc.PCBase
+++ jdoClass.getName() = org.apache.jdo.pc.PCDepartment1
+++ jdoClass.getName() = org.apache.jdo.pc.PCInsurance1
+++ jdoClass.getName() = org.apache.jdo.pc.PCEmployee1
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Person
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Project
!!! ReflectionJavaType.getDeclaredJavaField() inserts 'deptid'
as part of QueryImpl.compile(QueryImpl.java:454)
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Company
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Department
In contrast, here's the order with source=1.4, marking when
'deptid' get's inserted for the first time:
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Person
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Company
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Department
!!! ReflectionJavaType.createJavaField() inserts 'deptid'
as part of Class.forName()
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Insurance
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Employee
+++ jdoClass.getName() = org.apache.jdo.pc.PCBase
+++ jdoClass.getName() = org.apache.jdo.pc.PCDepartment1
+++ jdoClass.getName() = org.apache.jdo.pc.PCInsurance1
+++ jdoClass.getName() = org.apache.jdo.pc.PCEmployee1
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Project
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.FullTimeEmployee
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.PartTimeEmployee
+++ jdoClass.getName() = org.apache.jdo.pc.xempdept.PrimitiveTypes
Michael, any comments?
Is it an issue with the test, the model not being tolerant
about already added fields, or query.compile() populating
the Java model?
Michael Bouschen wrote:
>
> some remarks:
> - I'm surprised about the MissingResourceException for the key
> ERR_MultipleJavaField. Is there any difference in the bundle lookup in
> Java 5?
It's strange. I don't have an answer to that yet.
Thanks,
Martin
| |
| Martin Zaun 2005-09-22, 8:45 pm |
|
Michael,
after I had a closer look into Test_Query, I figured that you
might want to see a bit more stacktrace context around the
interesting points. So, more details below.
Martin
Martin Zaun wrote:
>
> - Checking the point of time when PC classes register with the
> runtime, it's different with source=1.5 versus 1.4!
>
> Here's the order with source=1.5, marking when 'deptid' get's
> inserted for the first time:
>
> +++ jdoClass.getName() = org.apache.jdo.pc.PCBase
> +++ jdoClass.getName() = org.apache.jdo.pc.PCDepartment1
> +++ jdoClass.getName() = org.apache.jdo.pc.PCInsurance1
> +++ jdoClass.getName() = org.apache.jdo.pc.PCEmployee1
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Person
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Project
> !!! ReflectionJavaType.getDeclaredJavaField() inserts 'deptid'
> as part of QueryImpl.compile(QueryImpl.java:454)
The full stacktrace at this point (line numbers +/- printlns):
at org.apache.jdo.impl.model.java.reflection.ReflectionJavaType.getDeclaredJavaField(ReflectionJavaType.java:241)
at org.apache.jdo.impl.model.java.reflection.ReflectionJavaType.getJavaField(ReflectionJavaType.java:177)
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.analyseDefinedIdentifier(Semantic.java:306)
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.identifier(Semantic.java:3328)
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.primary(Semantic.java:2839)
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.exprNoCheck(Semantic.java:1883)
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.expression(Semantic.java:1768)
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.relationalExpr(Semantic.java:2145)
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.exprNoCheck(Semantic.java:1822)
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.expression(Semantic.java:1768)
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.filter(Semantic.java:1264)
at org.apache.jdo.impl.jdoql.jdoqlc.Semantic.query(Semantic.java:1077)
at org.apache.jdo.impl.jdoql.jdoqlc.JDOQLC.semanticCheck(JDOQLC.java:261)
at org.apache.jdo.impl.jdoql.QueryImpl.compile(QueryImpl.java:454)
at org.apache.jdo.test.query.UnsupportedTest.unsupported001(UnsupportedTest.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.jdo.test.query.NegativeTest.runTest(NegativeTest.java:134)
at org.apache.jdo.test.query.NegativeTest.runAll(NegativeTest.java:93)
at org.apache.jdo.test.Test_Query.runQueryTestSuite(Test_Query.java:198)
at org.apache.jdo.test.Test_Query.testNegativeTests(Test_Query.java:117)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at org.apache.jdo.test.util.AbstractTest.runBare(AbstractTest.java:264)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:325)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:536)
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Company
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Department
At this point, in the registering of class Department, an attempt
is made to throw a ModelFatalException(ERR_MultipleJavaFiel
d):
at org.apache.jdo.impl.model.java.reflection.ReflectionJavaType.createJavaField(ReflectionJavaType.java:206)
at org.apache.jdo.impl.model.java.runtime.RegisterClassListener.updateJDOField(RegisterClassListener.java:173)
at org.apache.jdo.impl.model.java.runtime.RegisterClassListener.updateJDOClass(RegisterClassListener.java:154)
at org.apache.jdo.impl.model.java.runtime.RegisterClassListener.registerClass(RegisterClassListener.java:83)
at javax.jdo.spi.JDOImplHelper.registerClass(JDOImplHelper.java:288)
at org.apache.jdo.pc.xempdept.Department.<clinit>(Department.java)
Which causes this java.lang.ExceptionInInitializerError:
at org.apache.jdo.test.Test_Query.createObjects(Test_Query.java:346)
at org.apache.jdo.test.Test_Query.testMemoryQueries(Test_Query.java:129)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at org.apache.jdo.test.util.AbstractTest.runBare(AbstractTest.java:264)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:325)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:536)
>
> In contrast, here's the order with source=1.4, marking when
> 'deptid' get's inserted for the first time:
>
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Person
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Company
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Department
> !!! ReflectionJavaType.createJavaField() inserts 'deptid'
> as part of Class.forName()
The full stacktrace at this point:
at org.apache.jdo.impl.model.java.reflection.ReflectionJavaType.createJavaField(ReflectionJavaType.java:213)
at org.apache.jdo.impl.model.java.runtime.RegisterClassListener.updateJDOField(RegisterClassListener.java:173)
at org.apache.jdo.impl.model.java.runtime.RegisterClassListener.updateJDOClass(RegisterClassListener.java:154)
at org.apache.jdo.impl.model.java.runtime.RegisterClassListener.registerClass(RegisterClassListener.java:83)
at javax.jdo.spi.JDOImplHelper.registerClass(JDOImplHelper.java:288)
at org.apache.jdo.pc.xempdept.Department.<clinit>(Department.java)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at org.apache.jdo.pc.xempdept.Person.sunjdo$classForName$(Person.java)
at org.apache.jdo.pc.xempdept.Employee.<clinit>(Employee.java)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at org.apache.jdo.test.query.QueryErrorTest.class$(QueryErrorTest.java:71)
at org.apache.jdo.test.query.QueryErrorTest.queryError003(QueryErrorTest.java:125)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.jdo.test.query.NegativeTest.runTest(NegativeTest.java:134)
at org.apache.jdo.test.query.NegativeTest.runAll(NegativeTest.java:93)
at org.apache.jdo.test.Test_Query.runQueryTestSuite(Test_Query.java:198)
at org.apache.jdo.test.Test_Query.testNegativeTests(Test_Query.java:117)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at org.apache.jdo.test.util.AbstractTest.runBare(AbstractTest.java:264)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:325)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:536)
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Insurance
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Employee
> +++ jdoClass.getName() = org.apache.jdo.pc.PCBase
> +++ jdoClass.getName() = org.apache.jdo.pc.PCDepartment1
> +++ jdoClass.getName() = org.apache.jdo.pc.PCInsurance1
> +++ jdoClass.getName() = org.apache.jdo.pc.PCEmployee1
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.Project
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.FullTimeEmployee
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.PartTimeEmployee
> +++ jdoClass.getName() = org.apache.jdo.pc.xempdept.PrimitiveTypes
Test succeeds.
| |
| Martin Zaun 2005-09-22, 8:45 pm |
|
Michael,
Craig found the cause of the MissingResourceException.
[vbcol=seagreen]
> Michael Bouschen wrote:
BaseReflectionJavaType loads
org/apache/jdo/impl/model/java/Bundle.properties
which doesn't have an entry for ERR_MultipleJavaField.
Instead, ERR_MultipleJavaField is declared in the subdir
org/apache/jdo/impl/model/java/runtime/Bundle.properties
However, these two bundles seem to overlap a lot.
Maybe, we should go with only the parent bundle file ?
Martin
| |
| Martin Zaun 2005-09-23, 2:45 am |
|
Michael,
Craig and I had an in-depth discussion this afternoon on the
order-of-class-registration problem. Here's a summary:
1) The query's semantic analysis requires Java metadata (i.e.
name/type/existence of fields/classes), which we obtain by
reflection.
Reflection requires a class to be loaded and linked but not
neccessarily initialized (=static initializer executed).
The vmspec only mandates that initialization happens before
- an instance of the class is created,
- a static method of the class is invoked, or
- a nonconstant static field is used (read or assigned).
2) Apparently, there's a difference between source=1.4 and 1.5
on when class initialization happens. Source=1.5 seems to
result in a more deferred scheme.
This seems to explain the difference in the order of
registration of PC classes that we observe.
3) Does the query's semantic analysis require genuine JDO
metadata ?
JDO allows for in-memory query on even non-PC classes, if
I recall correctly. So, that would suggest that for query
compilation, we shouldn't require JDO metadata, while for
query execution we may need JDO (and mapping) metadata.
4) However, during/for the semantic analysis both models, Java
and JDO, seem to be populated (e.g JavaField and JDOField).
While JDOField has a PersistenceModifier status that covers
non-managed fields, a JDOClass instance always represents a
PC class. Is that a problem if we consider queries over
non-PC classes?
5) Depending on the answer to question 3), if the semantic
analysis needs all classes that are "touched" in a query
(navigational expressions) have registered, the query
compilation could enforce class initialization by calling
Class.forName().
As a hack, we changed QueryImpl.setClass() to ensure the
the target class is initialized:
try {
Class.forName(cls.getName(), true, cls.getClassLoader());
} catch (ClassNotFoundException ex) {
throw new RuntimeException(ex);
}
This hack fixes Query_Test with source=1.5 (but wouldn't
cover navigational expressions).
6) Depending on the answer to question 3), if the semantic
analysis does NOT need the classes to have registered, we
may want consider allowing for a partially populated java
model (JavaFields) upon class registration.
For this, we'd have to change
ReflectionJavaField.createJavaField()
to not throwing an exception. Something like this:
String name = jdoField.getName();
synchronized(javaFields) {
JavaField javaField = (JavaField)javaFields.get(name);
if (javaField == null) {
javaField = new ReflectionJavaField(jdoField, type, this);
javaFields.put(name, javaField);
}
return javaField;
}
7) Another option to consider is not populating the Java
model during semantic analysis (but class registration
only).
> - For a test, I changed ReflectionJavaType.getDeclaredJavaField()
> not to store the JavaField field in the private HashMap
> 'javaFields', and Test_Query runs fine then. But this doesn't
> look like the right approach to me.
This looks odd to me for we'd create JavaFields that we
wouldn't store in the Java model.
Thanks,
Martin
| |
| Martin Zaun 2005-09-29, 7:45 am |
|
Hi Michael,
thanks for the patch, only a few cosmetic comments inline, below.
I'll send out a summary of our discussion on the jdk 1.5 class
registration problem and the chosen approach later.
Martin
Michael Bouschen wrote:
> Hi Martin,
>
> attached you find a patch for the JDOModel implementation. It
> initializes a class instance if the model instance runs with the
> initialize=true flag. It also fixes the MissingResourceException. I
> could successfully run the ri tests in a workspace including your
> enhancer plus my JDOModel changes.
> I would port the JDOModel changes to core20 and check them in, if you
> agree with the changes.
>
> Regards Michael
>
>
>
>
>
>
> ------------------------------------------------------------------------
>
> Index: trunk/ri11/src/java/org/apache/jdo/impl/model/java/runtime/Bundle.properties
> ========================================
===========================
> --- trunk/ri11/src/java/org/apache/jdo/impl/model/java/runtime/Bundle.properties (Revision 292403)
> +++ trunk/ri11/src/java/org/apache/jdo/impl/model/java/runtime/Bundle.properties (Arbeitskopie)
> @@ -62,12 +62,3 @@
> #NOI18N
> ERR_CannotSetJDOModel=Cannot set JDOModel for JavaModel instance.
>
> -#
> -# RuntimeJavaType
> -#
> -
> -# {0} - error location (class.method)
> -# {1} - implementation method name
> -# {2} - field name
> -#NOI18N
> -ERR_MultipleJavaField={0}: multiple JavaField ''{1}'' for class '{2}''.
> Index: trunk/ri11/src/java/org/apache/jdo/impl/model/java/reflection/ReflectionJavaModel.java
> ========================================
===========================
> --- trunk/ri11/src/java/org/apache/jdo/impl/model/java/reflection/ReflectionJavaModel.java (Revision 292403)
> +++ trunk/ri11/src/java/org/apache/jdo/impl/model/java/reflection/ReflectionJavaModel.java (Arbeitskopie)
> @@ -87,8 +87,8 @@
> // loaded, Class.forName will load the class which
> // calls RegisterClassListener.registerClass.
> // This will create a new JavaType entry in the cache.
> - javaType = getJavaType(Class.forName(name, initialize,
> - classLoader));
> + javaType = getJavaTypeInternal(
> + Class.forName(name, initialize, classLoader));
> }
> catch (ClassNotFoundException ex) {
> // cannot find class => return null
> @@ -121,15 +121,20 @@
> */
> public JavaType getJavaType(Class clazz)
> {
> - String name = clazz.getName();
> - synchronized (types) {
> - JavaType javaType = (JavaType)types.get(name);
> - if (javaType == null) {
> - javaType = createJavaType(clazz);
> - types.put(name, javaType);
> + if (clazz == null)
> + return null;
> +
> + if (initialize) {
> + try {
> + // make sure the class is initialized
> + Class.forName(clazz.getName(), initialize, classLoader);
Since this is a public method, there's a chance for a bug that we're
called here with a class argument of a wrong classloader, I think.
If that happened, we'd load and initialize the class in the wrong
place. So, I'd change this line, making an assumption explicit, to:
Class.forName(clazz.getName(), initialize, clazz.getClassLoader());
Or, if we allowed for assertions, we could keep the line but just add:
assert (classLoader == clazz.getClassLoader());
> }
> - return javaType;
> + catch (ClassNotFoundException ex) {
> + // ignore
I'd add:
// ignore, since class has already been loaded
> + }
> }
> +
> + return getJavaTypeInternal(clazz);
> }
>
> /**
> @@ -170,6 +175,28 @@
> return classLoader;
> }
>
> + /**
> + * The method returns the JavaType instance for the type name of the
> + * specified class object. It first checks the cache and if there is no
> + * entry for the type name in the cache then it creates a new JavaType
> + * instance for the specified Class object.
> + * @param clazz the Class instance representing the type
> + * @return a JavaType instance for the name of the specified class
> + * object or <code>null</code> if not present in this model instance.
> + */
> + protected JavaType getJavaTypeInternal(Class clazz)
> + {
> + String name = clazz.getName();
> + synchronized (types) {
> + JavaType javaType = (JavaType)types.get(name);
> + if (javaType == null) {
> + javaType = createJavaType(clazz);
> + types.put(name, javaType);
> + }
> + return javaType;
> + }
> + }
> +
> /**
> * Creates a new JavaType instance for the specified Class object.
> * This method provides a hook such that ReflectionJavaModel subclasses
> Index: trunk/ri11/src/java/org/apache/jdo/impl/model/java/Bundle.properties
> ========================================
===========================
> --- trunk/ri11/src/java/org/apache/jdo/impl/model/java/Bundle.properties (Revision 292403)
> +++ trunk/ri11/src/java/org/apache/jdo/impl/model/java/Bundle.properties (Arbeitskopie)
> @@ -27,7 +27,7 @@
> EXC_ClassLoadingError=Error during loading of class ''{0}'': {1}.
>
> #
> -# ReflectionJavaType
> +# BaseReflectionJavaType
> #
>
> # {0} - error location (class.method)
> @@ -35,6 +35,16 @@
> ERR_InvalidNullClassInstance={0}: specified Class instance is null.
>
> #
> +# ReflectionJavaType
> +#
> +
> +# {0} - error location (class.method)
> +# {1} - implementation method name
> +# {2} - field name
> +#NOI18N
> +ERR_MultipleJavaField={0}: multiple JavaField ''{1}'' for class ''{2}''.
> +
> +#
> # BaseReflectionJavaField
> #
> # {0} - class name
| |
| Michael Bouschen 2005-09-29, 5:45 pm |
| Hi Martin,
thanks for the comments!
About the issue of a class argument of a wrong classloader passed to the
JavaModel method getJavaType: I agree the code should use the class
loader from the class object. The only issue is that the call
clazz.getClassLoader() might result in a SecurityException, so I need to
put this call into a doPrivileged block. I already have a convenience
method in RuntimeJavaModelFactory, I just need to move this method to a
class that is accessible in both places.
Regards Michael
>
> Hi Michael,
> thanks for the patch, only a few cosmetic comments inline, below.
> I'll send out a summary of our discussion on the jdk 1.5 class
> registration problem and the chosen approach later.
> Martin
>
> Michael Bouschen wrote:
>
>
>
> Since this is a public method, there's a chance for a bug that we're
> called here with a class argument of a wrong classloader, I think.
> If that happened, we'd load and initialize the class in the wrong
> place. So, I'd change this line, making an assumption explicit, to:
> Class.forName(clazz.getName(), initialize,
> clazz.getClassLoader());
> Or, if we allowed for assertions, we could keep the line but just add:
> assert (classLoader == clazz.getClassLoader());
>
>
>
> I'd add:
> // ignore, since class has already been loaded
>
>
--
Michael Bouschen Tech@Spree Engineering GmbH
mailto:mbo.tech@spree.de http://www.tech.spree.de/
Tel.:++49/30/235 520-33 Buelowstr. 66
Fax.:++49/30/2175 2012 D-10783 Berlin
| |
| Michael Bouschen 2005-09-30, 7:45 am |
| Hi Martin,
I checked in the Java model changes in ri11 and core20/runtime20
(revision 292681). From my point of view you can go ahead with your
enhancner support for jdk 1.5 changes :-).
Regards Michael
> Hi Martin,
>
> thanks for the comments!
>
> About the issue of a class argument of a wrong classloader passed to the
> JavaModel method getJavaType: I agree the code should use the class
> loader from the class object. The only issue is that the call
> clazz.getClassLoader() might result in a SecurityException, so I need to
> put this call into a doPrivileged block. I already have a convenience
> method in RuntimeJavaModelFactory, I just need to move this method to a
> class that is accessible in both places.
>
> Regards Michael
>
>
>
--
Michael Bouschen Tech@Spree Engineering GmbH
mailto:mbo.tech@spree.de http://www.tech.spree.de/
Tel.:++49/30/235 520-33 Buelowstr. 66
Fax.:++49/30/2175 2012 D-10783 Berlin
|
|
|
|
|