|
In Java, there is a difference between & and &&, but in JDOQL there is not. So the use of & is equivalent to &&.
None of the queries should use = since it is illegal in JDOQL. This test passes and has for a week at least
The test cases MixedVariables and VariablesAndFields fail throwing NoClassDefFoundError. Both test cases use implicit vairables.
14:22:31,328 (main) DEBUG [org.apache.jdo.tck] - Executing API query: SELECT FROM org.apache.jdo.tck.pc.company.Employee WHERE team.contains(employee) & employee.firstname == 'emp1First' 14:22:31,343 (main) INFO [org.apache.jdo.tck] - Exception during setUp or runtest: java.lang.NoClassDefFoundError: org/apache/jdo/tck/pc/company/employee (wrong name: org/apache/jdo/tck/pc/company/Employee) at java.lang.ClassLoader.defineClass0(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:539) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123) at java.net.URLClassLoader.defineClass(URLClassLoader.java:251) at java.net.URLClassLoader.access$100(URLClassLoader.java:55) at java.net.URLClassLoader$1.run(URLClassLoader.java:194) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:187) at java.lang.ClassLoader.loadClass(ClassLoader.java:289) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274) at java.lang.ClassLoader.loadClass(ClassLoader.java:235) at org.jpox.JDOClassLoaderResolver.classOrNull(JDOClassLoaderResolver.java:449) at org.jpox.JDOClassLoaderResolver.classForName(JDOClassLoaderResolver.java:140) at org.jpox.util.Imports.resolveClassDeclaration(Imports.java:152) at org.jpox.store.query.Query.resolveClassDeclaration(Query.java:844) at org.jpox.store.query.JDOQLQuery$Compiler.compileIdentifier(JDOQLQuery.java:1993) at org.jpox.store.query.JDOQLQuery$Compiler.compilePrimary(JDOQLQuery.java:1650) at org.jpox.store.query.JDOQLQuery$Compiler.compileUnaryExpressionNotPlusMinus(JDOQLQuery.java:1598) at org.jpox.store.query.JDOQLQuery$Compiler.compileUnaryExpression(JDOQLQuery.java:1579) at org.jpox.store.query.JDOQLQuery$Compiler.compileMultiplicativeExpression(JDOQLQuery.java:1532) at org.jpox.store.query.JDOQLQuery$Compiler.compileAdditiveExpression(JDOQLQuery.java:1509) at org.jpox.store.query.JDOQLQuery$Compiler.compileRelationalExpression(JDOQLQuery.java:1469) at org.jpox.store.query.JDOQLQuery$Compiler.compileEqualityExpression(JDOQLQuery.java:1446) at org.jpox.store.query.JDOQLQuery$Compiler.compileAndExpression(JDOQLQuery.java:1434) at org.jpox.store.query.JDOQLQuery$Compiler.compileExclusiveOrExpression(JDOQLQuery.java:1422) at org.jpox.store.query.JDOQLQuery$Compiler.compileInclusiveOrExpression(JDOQLQuery.java:1410) at org.jpox.store.query.JDOQLQuery$Compiler.compileConditionalAndExpression(JDOQLQuery.java:1398) at org.jpox.store.query.JDOQLQuery$Compiler.compileConditionalOrExpression(JDOQLQuery.java:1380) at org.jpox.store.query.JDOQLQuery$Compiler.compileExpression(JDOQLQuery.java:1357) at org.jpox.store.query.JDOQLQuery$Compiler.compilePrimary(JDOQLQuery.java:1699) at org.jpox.store.query.JDOQLQuery$Compiler.compileUnaryExpressionNotPlusMinus(JDOQLQuery.java:1598) at org.jpox.store.query.JDOQLQuery$Compiler.compileUnaryExpression(JDOQLQuery.java:1579) at org.jpox.store.query.JDOQLQuery$Compiler.compileMultiplicativeExpression(JDOQLQuery.java:1532) at org.jpox.store.query.JDOQLQuery$Compiler.compileAdditiveExpression(JDOQLQuery.java:1509) at org.jpox.store.query.JDOQLQuery$Compiler.compileRelationalExpression(JDOQLQuery.java:1469) at org.jpox.store.query.JDOQLQuery$Compiler.compileEqualityExpression(JDOQLQuery.java:1446) at org.jpox.store.query.JDOQLQuery$Compiler.compileAndExpression(JDOQLQuery.java:1434) at org.jpox.store.query.JDOQLQuery$Compiler.compileExclusiveOrExpression(JDOQLQuery.java:1422) at org.jpox.store.query.JDOQLQuery$Compiler.compileInclusiveOrExpression(JDOQLQuery.java:1410) at org.jpox.store.query.JDOQLQuery$Compiler.compileConditionalAndExpression(JDOQLQuery.java:1398) at org.jpox.store.query.JDOQLQuery$Compiler.compileConditionalOrExpression(JDOQLQuery.java:1380) at org.jpox.store.query.JDOQLQuery$Compiler.compileExpression(JDOQLQuery.java:1357) at org.jpox.store.query.JDOQLQuery$Compiler.compileExpressionFromString(JDOQLQuery.java:1287) at org.jpox.store.query.JDOQLQuery$Compiler.compileFilter(JDOQLQuery.java:1118) at org.jpox.store.query.JDOQLQuery$Compiler.performCompile(JDOQLQuery.java:920) at org.jpox.store.query.JDOQLQuery$Compiler.executionCompile(JDOQLQuery.java:905) at org.jpox.store.query.JDOQLQuery.performExecute(JDOQLQuery.java:622) at org.jpox.store.query.Query.executeWithMap(Query.java:966) at org.jpox.store.query.Query.executeWithArray(Query.java:939) at org.jpox.store.query.Query.execute(Query.java:862) at org.apache.jdo.tck.query.QueryTest.execute(QueryTest.java:1151) at org.apache.jdo.tck.query.QueryTest.execute(QueryTest.java:1029) at org.apache.jdo.tck.query.QueryTest.executeAPIQuery(QueryTest.java:966) at org.apache.jdo.tck.query.QueryTest.executeAPIQuery(QueryTest.java:946) at org.apache.jdo.tck.query.jdoql.variables.VariablesAndFields.testPositive(VariablesAndFields.java:152) 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:324) at junit.framework.TestCase.runTest(TestCase.java:154) at org.apache.jdo.tck.JDO_Test.runBare(JDO_Test.java:204) 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 junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at junit.textui.TestRunner.doRun(TestRunner.java:116) at junit.textui.TestRunner.doRun(TestRunner.java:109) at org.apache.jdo.tck.util.BatchTestRunner.start(BatchTestRunner.java:120) at org.apache.jdo.tck.util.BatchTestRunner.main(BatchTestRunner.java:95) And this is using what version of Subversion code exactly ? I'm using latest SVN and these tests still pass as mentioned previously.
Yesterday (Dec 19) I updated my workspace and ran all the tests.
I see the same errors (NoClassDefFoundError) as Michael Watzek described above. And I have a clean checkout of about 30 mins ago and still get no errors whatsoever on those tests. Perhaps something in your setup ? I use Linux and Maven 1.0.2. You use Windows don't you Michael ? The issue is more than likely some windows case-sensitivity or file separator issue.
Interesting! Yes, I'm using Windows. I think it has to do with queries using a variable with the same name as a class (modulo case). The above JDOQL query
SELECT FROM org.apache.jdo.tck.pc.company.Employee WHERE team.contains(employee) & employee.firstname == 'emp1First' defines an implicit variable called employee where Employee is the base name of the candidate class. It does not matter whether the variable is defined implicitly or explicitly. The problem disappears if I change the variable name to e.g. 'emp'. The method names in the stack trace suggest that JPOX tries to resolve the identifier 'employee' as class name. Is that the case. Which occurrence of 'employee' is causing the problem, the contains argument or the left hand side of the equals comparison? JPOX would have to check for whether something is a class or not before falling back to "implicit variable". As for which variable "employee" is the issue I've no idea ... but then I don't see the issue so can't debug it. The stack trace line numbers provided by Michael above don't correspond to what I have in JPOX CVS either. Provide a valid stack trace using the most recent JPOX build, and just the part like the following
at org.jpox.util.Imports.resolveClassDeclaration(Imports.java:152) at org.jpox.store.query.Query.resolveClassDeclaration(Query.java:844) at org.jpox.store.query.JDOQLQuery$Compiler.compileIdentifier(JDOQLQuery.java:1993) at org.jpox.store.query.JDOQLQuery$Compiler.compilePrimary(JDOQLQuery.java:1650) Without valid line numbers I can't do a thing. This is a part of the stack trace from todays run using the JPOX build available today:
... at java.lang.ClassLoader.loadClass(ClassLoader.java:235) at org.jpox.JDOClassLoaderResolver.classOrNull(JDOClassLoaderResolver.java:449) at org.jpox.JDOClassLoaderResolver.classForName(JDOClassLoaderResolver.java:140) at org.jpox.util.Imports.resolveClassDeclaration(Imports.java:152) at org.jpox.store.query.Query.resolveClassDeclaration(Query.java:844) at org.jpox.store.query.JDOQLQuery$Compiler.compileIdentifier(JDOQLQuery.java:2019) at org.jpox.store.query.JDOQLQuery$Compiler.compilePrimary(JDOQLQuery.java:1676) at org.jpox.store.query.JDOQLQuery$Compiler.compileUnaryExpressionNotPlusMinus(JDOQLQuery.java:1624) at org.jpox.store.query.JDOQLQuery$Compiler.compileUnaryExpression(JDOQLQuery.java:1605) ... Please let me know in case you need more. Thanks for the stack trace Michael. Seems that some Windows JREs sometimes throw a NoClassDefFoundError and Unix JREs dont - nice consistent platform-independent approach. JPOX CVS (builds from 22/12/2005 onwards) now checks for this and acts accordingly. Give it a try since I can't :-)
Sorry Andy, this seems to be a JRE problem when running on Windows. I tried, but the problem remains:
at java.lang.Class.forName(Class.java:141) at org.jpox.JDOClassLoaderResolver.classForName(JDOClassLoaderResolver.java:164) at org.jpox.util.Imports.resolveClassDeclaration(Imports.java:152) at org.jpox.store.query.Query.resolveClassDeclaration(Query.java:844) at org.jpox.store.query.JDOQLQuery$Compiler.compileIdentifier(JDOQLQuery.java:2082) I did a simple test case. A Class.forName("foo.bar") when there is a class foo.Bar results in the same exception when running on Windows. I propose I change the test case and rename the variable from employee to emp to avoid the Windows issue. I assigned the issue to me already. We are going to file a bug on the JRE saying that behavior for classes that don't exist is inconsistent based on the platform and the name. Specifically, it seems that Windows platforms get confused trying to resolve class names that differ in capitalization from real class names.
There are two action items to take away. 1. JDO implementations should behave defensively and treat both NoClassDefFoundError and ClassNotFoundException as "class does not exist". There is no reason to expect that Sun will timely fix this defect in the relevant Java platforms that JDO implementations support. 2. TCK test cases should be changed to avoid using variable names that conflict modulo capitalization with class names. I changed the variable names in test classes MixedVariables and VariablesAndFields to avoid a conflict modulo capitalization with class names.
I found and fixed the same issue in the following test classes: - org.apache.jdo.tck.query.delete.DeleteQueryElements - org.apache.jdo.tck.query.api.SingleStringQuery - org.apache.jdo.tck.query.api.ChangeQuery - org.apache.jdo.tck.query.jdoql.keywords.SingleString - org.apache.jdo.tck.query.result.NPEInResultExpr - org.apache.jdo.tck.query.result.VariableInResult - org.apache.jdo.tck.query.result.ResultExpressions.java - org.apache.jdo.tck.query.result.DistinctCandidateInstances > JDO implementations should behave defensively and treat both NoClassDefFoundError and ClassNotFoundException as "class does not exist".
FWIW. That is what JPOX builds have been doing since about 4 days ago. > JDO implementations should behave defensively and treat both NoClassDefFoundError and ClassNotFoundException as "class does not exist".
In fact, this does not only include NoClassDefFoundErrors but LinkageErrors in general, see below. >We are going to file a bug on the JRE saying that behavior for classes that don't exist is inconsistent based on the platform and the name. Specifically, it seems that Windows platforms get confused trying to resolve class names that differ in capitalization from real class names. The JRE's behaviour doesn't strike me as inconsistent with the Java specs after consulting the Java Language Specification (3rd edition) http://java.sun.com/docs/books/jls/index.html and, more detailed, the revised chapter 5 "Loading, Linking and Initializing" of the the Java VM Specification (2nd edition + latest amendments): http://java.sun.com/docs/books/vmspec/2nd-edition/ConstantPool.pdf In a nutshell: 1) A ClassNotFoundException is thrown when no binary representation of a class could be found at all; a LinkageError, including NoClassDefFoundError, is thrown when some representation was found but it's "content" turns out not to be a feasible or the required class. 2) ClassLoader.loadClass() is a place where LinkageErrors may occur. (There are rules about when classloaders, which may employ an eager or lazy loading strategy, may throw such errors). 3) The process of finding of a binary representation of a class is specified as platform-dependent -- even for the bootstrap classloader. Note that user-defined classloaders have all freedom anyway (for instance, loading classes over the net). So, a classloader may, by its rules, report to have located a binary representation for a class name, which then turns out not to be the required class, thus, resulting in a LinkageError. The VM spec is explicit on this: 5.3.1 Loading Using the Bootstrap Class Loader The following steps are used to load and thereby create the nonarray class or interface C denoted by N using the bootstrap class loader. ... 1. The Java virtual machine searches for a purported representation of C in a platform- dependent manner. Note that there is no guarantee that a purported representation found is valid or is a representation of C. Typically, a class or interface will be represented using a file in a hierarchical file system. The name of the class or interface will usually be encoded in the pathname of the file. This phase of loading must detect the following error: * If no purported representation of C is found, loading throws an instance of NoClassDefFoundError or an instance of one of its subclasses. |
||||||||||||||||||||||||||||||||||||||||||||||||||
query.jdoql.variables.VariablesAndFields
* several of the queries use & when they should use &&
* several of the queries use = when they should use ==