Hello I am receiving this error and I am unsure why. I am just
performing a query on a collection of a simple type using an alias. I
hope someone can help me!
I am using open-jdk-1.6
Exception in thread "main" java.lang.NoClassDefFoundError: net/sf/cglib/proxy/Callback
at com.mysema.query.alias.Alias.<clinit>(Alias.java:44)
at TestingMain.main(TestingMain.java:23)
Caused by: java.lang.ClassNotFoundException: net.sf.cglib.proxy.Callback
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
... 2 more
Here is a sample of the code
ArrayList<TestClass> testSource = new ArrayList<TestClass>();
testSource.add(new TestClass("old timer", 89));
testSource.add(new TestClass("bob", 22));
testSource.add(new TestClass("joe", 24));
TestClass test = alias(TestClass.class, "TestClass");
List<TestClass> tests = from($(test),testSource)
.where($(test.getAge()).in(24))
.list($(test));
for (TestClass t : tests)
{
System.out.println(t.getName());
}
Thank you so much!
timowestThe cglib dependency comes from querydsl-core :
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
Make sure CGLIB is visible from your project. I haven't tested querydsl-collections with OpenJDK, but it should definitely work.
Is net.sf.cglib.proxy.Enhancer visible?
If you use Eclipse, make sure cglib 2.2 is visible as an dependency in your project.
The path to the dependency is
querydsl-collection > querydsl-core > cglib
If switching to a Sun JDK is an option, then this could be tried too.
halasearWhere would this dependency be located? I am rather new to how Maven
works (I come from a .Net development background). Would I have to find
it within the repository for which Maven saves the dependencies to? (in
the $USER/.m2/repository/ directory (in a unix-like environment))?
Is
there a reason why Maven does not create a jar that compiles all of the
dependencies into one instead of having to find and locate all of the
dependencies individually? I think that is what is the most frustrating
aspect of getting this very useful library to work.
The OpenJDK
is the open sourced SunJDK (same code base), so I would think it should
not make a difference. It's not like it's the GNU JDK (different code
base).
Thanks again for all of the help!
Additionally, I am using Eclipse
timowestWhere would this dependency be located? I am rather
new to how Maven works (I come from a .Net development background).
Would I have to find it within the repository for which Maven saves the
dependencies to? (in the $USER/.m2/repository/ directory (in a unix-like
environment))?
Yes, it is fetched into your local repository from a remote one (e.g.
http://repo1.maven.org).
Is there a reason why Maven does not create a jar that compiles all of the dependencies into one instead of having to find and locate all of the dependencies individually?
The pom.xml declares the dependencies and Maven fetches them. So not really much to manage manually.
I think that is what is the most frustrating aspect of getting this very useful library to work.
If you don't use Maven to do your builds you can request an alternative way to package Querydsl.
We could for example provide zip or tgz files with all the dependencies of the hql, sql, jdoql and collections modules.
We at Mysema and probably also most of the Querydsl users use Maven, so until there was no need for an alternative packaging.
If
you want to keep on using Maven then you could for example run the
following Maven command in your project to get a proper eclipse setup
for it
mvn -DdownloadSources eclipse:clean eclipse:eclipse
This will set you up with an Eclipse project with proper Maven dependencies.
If you use IDEA then the following goal will do the job
mvn idea:clean idea:idea
But
if you want to use Querydsl without Maven, just tell me, and we will
provide releases with all needed jars packaged in zips and/or tgz files.
Here are some Maven IDE integration links :
IDEA :
http://maven.apache.org/plugins/maven-idea-plugin/usage.htmlEclipse :
http://maven.apache.org/plugins/maven-eclipse-plugin/http://maven.apache.org/eclipse-plugin.htmlhalasearOhh I get it now! I didn't realize that there were separate projects
created for each package. I had run the command from another thread that
you had commented in (a little different from the one from the
documentation).
Thank you so much, this makes so much more sense!
It will not be necessary for you to create a combined jar, not after I
have figured out how to get all of the projects to work with their
dependencies. I had actually already installed the maven plugin for
eclipse, I just didn't quite understand how it worked.
So again,
unfortunately, when I run the same blip of code I still get an error,
though it's a different one. I am currently running 1.1.7, would that
make a difference? I noticed that 1.2.0 has been released.
Exception in thread "main" java.lang.RuntimeException
at com.mysema.query.util.FactoryMap.get(FactoryMap.java:50)
at com.mysema.query.alias.AliasFactory.createAliasForVariable(AliasFactory.java:55)
at com.mysema.query.alias.Alias.alias(Alias.java:155)
at TestingMain.main(TestingMain.java:23)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.mysema.query.util.FactoryMap.get(FactoryMap.java:46)
... 3 more
Caused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at net.sf.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
at com.mysema.query.alias.AliasFactory.createProxy(AliasFactory.java:73)
at com.mysema.query.alias.AliasFactory.access$0(AliasFactory.java:60)
at com.mysema.query.alias.AliasFactory$2.create(AliasFactory.java:38)
... 8 more
Once again, thank you so much I greatly appreciate all of the help that you have given me!
And I would like to add that cglib is included!
timowestCaused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
This
happens if you try to create an alias instance for a class without a
public empty constructor. Cglib subclasses the given type dynamically
and it needs a public empty constructor to instantiate them.
So make sure that the classes you use for Alias-usage have an empty constructor.
halasearWell, you make it sound so easy!
I didn't think it was pertaining to my class. Again, thank you so much!
timowest> Well, you make it sound so easy!
;) I have used Hibernate quite a lot, which has similar restrictions.
I willl mention this restriction in the documentation.
halasearOkay, now I am trying to reproduce the use of the PEntity. However, it
is complaining about invalid type (which makes sense) for testClass
static variable. However the documentation of 3.1.1 "Best Practices"
essentially performs the following.
import com.mysema.query.types.path.*;
public class QTestClass extends PEntity<TestClass> {
public static final TestClass testClass = new QTestClass("testClass");
public QTestClass(String variable) {
super(TestClass.class, PathMetadataFactory.forVariable(variable));
}
}
then
from looking at the example of the documentation for 2.3 querying
collections it discusses the following in 2.3.2. Which I am trying to
replicate as follows. This too does not as the documentation lists
(which once again makes sense because the String class does not contain
the following functions.)
TestClass test2 = QTestClass.testClass;
for (TestClass t : select(testSource, test2.getName().in("bob"))){
System.out.println(t.getName());
}
Thanks again, I really appreciate all of the help.
Is there a test project that contains examples?
timowestHere is a working example for your case :
public class SimpleTest {
public static class TestClass {
private int age;
private String name;
public TestClass(String name, int age){
this.name = name;
this.age = age;
}
public TestClass(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public static class QTestClass extends PEntity<TestClass> {
public static final QTestClass testClass = new QTestClass("testClass");
public final PString name = createString("name");
public final PNumber<Integer> age = createNumber("age",Integer.class);
public QTestClass(String variable) {
super(TestClass.class, PathMetadataFactory.forVariable(variable));
}
}
@Test
public void test(){
List<TestClass> testSource = new ArrayList<TestClass>();
testSource.add(new TestClass("old timer", 89));
testSource.add(new TestClass("bob", 22));
testSource.add(new TestClass("joe", 24));
QTestClass tc = QTestClass.testClass;
for (TestClass t : MiniApi.from(tc, testSource).where(tc.name.eq("bob")).list(tc)){
System.out.println(t.getName());
}
for (TestClass t : MiniApi.from(tc, testSource).where(tc.name.in("bob")).list(tc)){
System.out.println(t.getName());
}
}
}
There is an error in the reference's Best Practices section. The correct form for default variables is
QAccount extends PEntity<Account>{
public static final Account account = new QAccount("account");
}
If you want to automatically create Querydsl query types (PEntity
subclasses) for your domain types, you can annotate them with the
QueryEntity annotation and adding the following plugin configuration
into your project's Maven configuration (pom.xml) :
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>maven-apt-plugin</artifactId>
<version>0.3.0</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.mysema.query.apt.QuerydslAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
This will also be properly document in the next release's reference documentation.
For more examples see the unit tests for querydsl-collections. They are in the src/test/java folder.
Sorry, the form for default variables is of course :
QAccount extends PEntity<Account>{
public static final QAccount account = new QAccount("account");
}
halasear
Sweet! Thanks a million!
I will test these later tonight!
Cyberax
A 'small' request - maybe you can add a cache of compiled expressions?
I've accidentally used qdsl-collections in an internal loop and it
HURTs.
timowest
Ok, will do that and let you know when it's finished.
Alex (aka Cyberax), can you give my an example that is really slow with the current implementation?
There is an compilation overhead for first-time queries, but subsequent iterations are faster.
Without real examples it is difficult to promise any improvement, I don't want to optimize wrong aspects ;)