Issue Details (XML | Word | Printable)

Key: EJB-242
Type: Improvement Improvement
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Emmanuel Bernard
Reporter: Michał Kostrzewa
Votes: 6
Watchers: 5
Operations

If you were logged in you would be able to see more operations.
z - Hibernate Entity Manager

Be more defensive regarding exotic (aka buggy) URL protocol handler

Created: 20/Oct/06 04:01 AM   Updated: 21/Feb/07 03:27 PM   Resolved: 15/Feb/07 04:04 PM
Component/s: EntityManager
Affects Version/s: 3.2.0.ga
Fix Version/s: 3.3.0.ga

Time Tracking:
Not Specified

Environment: Hibernate 3.2.0 GA, postgres (but I guess not relevant here)
Issue Links:
Relates
 

Participants: Emmanuel Bernard, Enrico Schnepel, Michał Kostrzewa and Wolfgang Schramm


 Description  « Hide

Hi,

Max from user list kindly redirected me to fill a bug here. Here it goes as I described it on list. I didn't attached a test case b/c doing it is non-trivial, maybe you'll just know what is the problem and I provided a patch that works for me. But if test case is needed - I'll do it.

--------------

I'm having problems with bundling hibernate and my ejb model in eclipse RCP application. I managed to solve all classloading problems but one, related to InputStreamZippedJarVisitor class.

Simplifying things I have:

hibernate plugin which registers itself for buddy classloading policy

dbmodel plugin which depends on hibernate and is a buddy of hibernate

application plugin which depends on hibernate and dbmodel and is a buddy of hibernate. This application plugin has hibernate.cfg.xml in self.

When I run this project from eclipse IDE, all is fine except the warning message in logs while creating EntityManager:

2006-10-20 09:07:23 org.hibernate.ejb.packaging.InputStreamZippedJarVisitor doProcessElements
WARNING: Unable to find file (ignored): bundleresource://101
java.io.FileNotFoundException: C:\Documents and Settings\mkostrze\sv-head2\com.pentacomp.dbmodel (Access denied)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at org.eclipse.osgi.framework.util.SecureAction.getFileInputStream(SecureAction.java:99)
at org.eclipse.osgi.baseadaptor.bundlefile.FileBundleEntry.getInputStream(FileBundleEntry.java:50)
at org.eclipse.osgi.framework.internal.core.BundleURLConnection.connect(BundleURLConnection.java:53)
at org.eclipse.osgi.framework.internal.core.BundleURLConnection.getInputStream(BundleURLConnection.java:99)
at java.net.URL.openStream(URL.java:1007)
at org.hibernate.ejb.packaging.InputStreamZippedJarVisitor.doProcessElements(InputStreamZippedJarVisitor.java:33)
at org.hibernate.ejb.packaging.JarVisitor.getMatchingEntries(JarVisitor.java:215)
at org.hibernate.ejb.Ejb3Configuration.addMetadataFromVisitor(Ejb3Configuration.java:253)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:229)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:120)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:51)
at com.pentacomp.dicom.viewer.ViewerContstants.createEntityManager(ViewerContstants.java:170)
at com.pentacomp.dicom.viewer.DicomViewerMainFrame$InitRepositoriesTask.call(DicomViewerMainFrame.java:146)

I suppose hibernate tries to inspect the model jar for some reason, but in IDE this jar location is resolved to directory containing the plugin.

But things get worse when I export the project into java webstart application. I'm getting NullPointerException instead of warning in the same place. I investigated the source and the problem is here:

protected void doProcessElements() throws IOException {
JarInputStream jis;
try { jis = new JarInputStream( jarUrl.openStream() ); }
catch (IOException ze) { log.warn( "Unable to find file (ignored): " + jarUrl, ze ); return; }

The jarUrl is a bundleresource:// url which resolves to DirZipBundleEntry which in turn returns null in getInputStream(). Thus JarInputStream thows NPE.

Here's what I've tried to solve this:

  • configure the dbmodel to be unpacked or packed after install
  • tried dbmodel with jar inside or with unpacked classes inside
  • set hibernate.archive.autodetection to 'none'. (I did it passing parameters map to createEntityManager method)
  • change the hibernate sources and replace IOException with Exception in doProcessElement method. This one worked

I guess most likely I did something wrong to my deploy - any ideas please? But if not, perhaps such a change in code may make hibernate more robust

Hibernate version: 3.2.0 GA

best regards,
Michal Kostrzewa



Emmanuel Bernard added a comment - 20/Oct/06 01:07 PM

Hum, The code has been change at least 3 times to cope with Eclipse RCP.
I know HEM in RCP is working (at least some people reported so).

I don't know the exact issue you are facing. Can you attach a minimal failing testcase?

Also I would appreciate if you could try something like that:

in JarVisitor.getJarURLFromURLEntry
add a
else if ("bundleresource".equals( url.getProtocol() ) {
//we don't know for sure, but this is probably eclipse, there is no way to guess more
jarUrl = new URL( protocol, url.getHost(), url.getPort(), file );
jarUrl = FileLocator.toFileURL(jarUrl);
//or maybe jarUrl = FileLocator.resolve(jarUrl);
}

As for your NPE, there is a bug in Eclipse, if the protocol does not support openStream, it is supposed to raise throw new UnknownServiceException("protocol doesn't support input");
This does not solve the problem in any way though.


Wolfgang Schramm added a comment - 20/Dec/06 02:25 AM

I had exactly the same problem, the rcp app worked in the IDE but not when it was exported as a product.

Replacing IOException with Exception in the doProcessElement() method solved this problem. Instead of an NPE a warning is now logged.

Log with IOException

09:13:36,151 DEBUG Ejb3Configuration:544 - Detect class: false; detect hbm: false
09:13:36,151 DEBUG JarVisitor:206 - Searching mapped entities in jar/par: bundleresource://4
...
Caused by: javax.persistence.PersistenceException: java.lang.NullPointerException: in is null
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:252)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:120)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:51)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33)
at net.tourbook.database.TourDatabase$1.run(TourDatabase.java:120)
...
Caused by: java.lang.NullPointerException: in is null
at java.util.zip.ZipInputStream.<init>(Unknown Source)
at java.util.jar.JarInputStream.<init>(Unknown Source)
at java.util.jar.JarInputStream.<init>(Unknown Source)
at org.hibernate.ejb.packaging.InputStreamZippedJarVisitor.doProcessElements(InputStreamZippedJarVisitor.java:33)
at org.hibernate.ejb.packaging.JarVisitor.getMatchingEntries(JarVisitor.java:229)
at org.hibernate.ejb.Ejb3Configuration.addMetadataFromVisitor(Ejb3Configuration.java:258)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:234)
...

Log with Exception

09:21:06,208 DEBUG Ejb3Configuration:544 - Detect class: false; detect hbm: false
09:21:06,208 DEBUG JarVisitor:206 - Searching mapped entities in jar/par: bundleresource://4
09:21:06,218 WARN InputStreamZippedJarVisitor:36 - Unable to find file (ignored): bundleresource://4
java.lang.NullPointerException: in is null
at java.util.zip.ZipInputStream.<init>(Unknown Source)
at java.util.jar.JarInputStream.<init>(Unknown Source)
at java.util.jar.JarInputStream.<init>(Unknown Source)
at org.hibernate.ejb.packaging.InputStreamZippedJarVisitor.doProcessElements(InputStreamZippedJarVisitor.java:33)
at org.hibernate.ejb.packaging.JarVisitor.getMatchingEntries(JarVisitor.java:229)
at org.hibernate.ejb.Ejb3Configuration.addMetadataFromVisitor(Ejb3Configuration.java:258)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:234)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:120)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:51)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33)


Michał Kostrzewa added a comment - 20/Dec/06 02:37 AM

To my suprise I noticed I didn't comment this bug after I found a workaround some time ago - I lived in conciousness of having posted this, I'm terribly sorry it may have saved Wolfgang some investigations...

As far as I rememember the fix provided by Emmanuel didn't work for me (but I'm only 99% sure about it, since I tried it some time ago)

I solved it exactely the way Wolfgang did, actually I did it earlier so I even survived one ecplipse RCP upgrade which happily spoiled nothing. I'd also like to acknowledge that this solution works when application is exported as Java Web Start application, which is non-obvious, yet works.


Emmanuel Bernard added a comment - 15/Feb/07 03:18 PM

Alright, I'' do it, but please someone provide me a test case for EJB-270


Enrico Schnepel added a comment - 21/Feb/07 11:19 AM

I found a workaround - you have to extract all of the eclipse-generated entity jars in the product plugin dir into seperate folders (entities_1.0.0.jar => entities_1.0.0/) and remove the jars. This will give you an other warning (InputStreamZippedJarVisitor:36 - Unable to find file (ignored): bundleresource://62) and a FileNotFoundException, but hibernate does work...


Michał Kostrzewa added a comment - 21/Feb/07 03:27 PM

I'm not sure how (if) the latest suggestion will work in Java Web Start environment, all the plugins need to be packed here... What do you think?
About test case - I'll try to prepare one, but it may take a while to do suitable and minimal test case, please don't hold your breath...