-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: EntityManager cannot find package annotations
PostPosted: Sun Dec 11, 2005 4:39 pm 
Newbie

Joined: Wed Jan 05, 2005 8:20 pm
Posts: 10
The problem is not really related to Hibernate, but there is a workaround that the Hibernate developers may choose to implement.

When using a package annotation in hibernate you end up specifying the package in the persistence.xml file with a Hibernate-specific extension:

<class>path.to.my.package</class>

Note that this references a package and not an annotated Class. This entry will cause Hibernate to eventually call Package.getPackage("path.to.my.package"). The JavaDoc states that the return value can be null "..if no package information is available from the archive or codebase."

Apparently, the return value can also be null simply because the ClassLoaders don't feel like looking to hard for the information. The author of this article (http://www.javaworld.com/javaworld/jw-0 ... -jpvs.html) refers to this behavior as an optimization. I think this is more likely a JDK bug, but I can't find any open bugs for it.

Here is what I think may be a workaround for the problem. Since the EntityManager is looking for a specific class in this package, a call to:

Code:
Class.forName("path.to.my.package.package-info")


causes the Package.getPackage(name) call to succeed.

Hibernate version:
Hibernate EntityManager 3.1beta4
Using as a stand-alone container

Mapping documents:
Using annotations

Full stack trace of any exception that occurs:
java.lang.IllegalArgumentException: class or package not found
at org.hibernate.ejb.Ejb3Configuration.createEntityManagerFactory(Ejb3Configuration.java:149)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:73)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:37)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:27)
at TestConnection.main(TestConnection.java:13)
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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Caused by: java.lang.IllegalArgumentException: class or package not found
at org.hibernate.ejb.Ejb3Configuration.addNamedAnnotatedClasses(Ejb3Configuration.java:558)
at org.hibernate.ejb.Ejb3Configuration.createEntityManagerFactory(Ejb3Configuration.java:387)
at org.hibernate.ejb.Ejb3Configuration.createFactory(Ejb3Configuration.java:96)
at org.hibernate.ejb.Ejb3Configuration.createEntityManagerFactory(Ejb3Configuration.java:142)
... 9 more
Caused by: java.lang.ClassNotFoundException: us.oh.state.dot.hibernate
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:108)
at org.hibernate.ejb.Ejb3Configuration.addNamedAnnotatedClasses(Ejb3Configuration.java:552)
... 12 more

Process finished with exit code 1
[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 11, 2005 5:49 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
This is exactly what I do.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 11, 2005 6:33 pm 
Newbie

Joined: Wed Jan 05, 2005 8:20 pm
Posts: 10
Quote:
This is exactly what I do.


I'm assuming you mean you use the Class.forName() approach.

Unfortunately, this approach has some problems when using it standalone and the EntityManager is bootstrapped by some other process before you have a chance to execute the Class.forName.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 12, 2005 5:00 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
I don't see what you're talking about.
When standalone and bootstraped by something else, HEM load the class package-info according to the current tread context classloader (and degrade to this.class.getClassloader() if not found)
I don't see how this could be a problem.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 12, 2005 9:36 am 
Newbie

Joined: Wed Jan 05, 2005 8:20 pm
Posts: 10
It's a problem because the Package.getPackage(name) method will sometimes return null even when that package is in the classpath. It happens to me when I run on Windows using JDK 1.5_05 from Sun. This method is used by the HEM to resolve package-level annotations.

The author of the article I referred to mentions that this is an optimization that the JDK may choose to employ. I have written a bit of test code to see that it is indeed occurring on my machine.

For example, the following code returns null:

Code:
public static void main(String[] args) throws Exception {
    Package pkg = Package.getPackage("path.to.my.beans");
    System.out.println("pkg = " + pkg);
}


This code actually returns a value:

Code:
public static void main(String[] args) throws Exception {
    Class.forName("path.to.my.beans.package-info");
    Package pkg = Package.getPackage("path.to.my.beans");
    System.out.println("pkg = " + pkg);
}


If I don't force the Class.forName() call, the HEM fails with the NPE I included. I thought you guys may want to include code before calling Package.getPackage() that does the Class.forName() method call to handle the cases where the bootstrapping of the HEM is out of the developers control. For example, when used in some IoC containers.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 12, 2005 1:06 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Look at the code, this is exactly what I do.

Code:
pckg = ReflectHelper.classForName( packageName + ".package-info" ).getPackage();


I never use Package.getPackage

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 12, 2005 1:40 pm 
Newbie

Joined: Wed Jan 05, 2005 8:20 pm
Posts: 10
I'm using the 3.1beta4 version or HEM. I'm also instantiating the HEM standalone via the factory. When I do this, the following method in the Ejb3Configuration class is invoked:

Code:
private void addNamedAnnotatedClasses(Ejb3Configuration cfg, Collection<String> classNames) {
   for ( String name : classNames ) {
      try {
         Class clazz = ReflectHelper.classForName( name );
         cfg.addAnnotatedClass( clazz );
      }
      catch (ClassNotFoundException cnfe) {
         Package pkg = Package.getPackage( name );
         if ( pkg == null ) {
            throw new IllegalArgumentException( "class or package not found", cnfe );
         }
         else {
            cfg.addPackage( name );
         }
      }
   }
}


It's this code that is calling Package.getPackage(name).


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 13, 2005 7:11 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
ah, cool. I'll fix that for the release.

_________________
Emmanuel


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.