-->
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.  [ 7 posts ] 
Author Message
 Post subject: Slow startup
PostPosted: Thu Jan 07, 2016 4:50 am 
Newbie

Joined: Thu Jan 07, 2016 4:17 am
Posts: 4
Hi,

When I startup my Glassfish server and load hibernate it takes a very long time to load the .hbm.xml mapping files.

I profiled this:

Code:
  34,5% - 22.819 ms - 196 inv. org.dom4j.io.SAXReader.read(org.xml.sax.InputSource)
  32,8% - 21.686 ms - 196 inv. org.hibernate.cfg.EJB3DTDEntityResolver.resolveEntity
  32,8% - 21.685 ms - 196 inv. org.hibernate.internal.util.xml.DTDEntityResolver.resolveEntity
  32,8% - 21.670 ms - 196 inv. org.hibernate.internal.util.xml.DTDEntityResolver.resolveInLocalNamespace
  32,8% - 21.670 ms - 196 inv. org.hibernate.internal.util.ConfigHelper.getUserResourceAsStream
  32,8% - 21.669 ms - 196 inv. java.lang.ClassLoader.getResourceAsStream


And as you see the problem seems to be in the DTD resolver. The first time it is called it scans the whole classpath (including glassfish) and it takes 21 seconds to do this. This delay is only noticeable the first hbm.xml mapping file is loaded. All DTD's after the first one resolv in less than 2 ms.

All my hbm.xml files have the following DTD's:

Code:
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


I had a look at the source code of the entity resolver:

Code:
public InputSource resolveEntity(String publicId, String systemId) {
      InputSource source = null;
      if(systemId != null) {
...
         if(systemId.startsWith("http://www.hibernate.org/dtd/")) {
            ...
            source = this.resolveOnClassPath(publicId, systemId, "http://www.hibernate.org/dtd/");
         } else if(systemId.startsWith("http://hibernate.sourceforge.net/")) {
          ..
            source = this.resolveOnClassPath(publicId, systemId, "http://hibernate.sourceforge.net/");
         } else if(systemId.startsWith("classpath://")) {



And tried www.hibernate.org as well as classpatj:// but they all scan the whole classpath.

The DTD is located in the hibernate JAR and it works perfectly but it is just slow.

Is there any way I can speed this up?

Additional information:
Hibernate version: 4.1.7
Glassfish: 3.1.2.2

Thanks for having a look!


Top
 Profile  
 
 Post subject: Re: Slow startup
PostPosted: Thu Jan 07, 2016 4:59 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
Try changing the DTD declaration like this:

Code:
<!DOCTYPE hibernate-configuration SYSTEM "classpath://org/hibernate/hibernate-configuration-3.0.dtd">


as indicated in this StackOverflow answer: http://stackoverflow.com/questions/10886453/hibernate-issue-with-using-http-www-hibernate-org-dtd


Top
 Profile  
 
 Post subject: Re: Slow startup
PostPosted: Thu Jan 07, 2016 5:50 am 
Newbie

Joined: Thu Jan 07, 2016 4:17 am
Posts: 4
Hi,

Thank you very much for looking at this issue.

I tried your suggestion but unfortunatly this gives the same result. In the DTDEntityResolver you now come into this part:

Code:
} else if(systemId.startsWith("classpath://")) {
            LOG.debug("Recognized local namespace; attempting to resolve on classpath");
            String path = systemId.substring("classpath://".length());
            InputStream stream = this.resolveInLocalNamespace(path);


The resolvInLocatlNamespace(path) method does:

Code:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
      if ( classLoader != null ) {
         stream = classLoader.getResourceAsStream( resource );
         if ( stream == null && hasLeadingSlash ) {
            stream = classLoader.getResourceAsStream( stripped );
         }
      }


which scans the whole classpath at the first call. In the profiler this takes 22 seconds:

Code:
68,0% - 22.312 ms - 196 inv. org.hibernate.internal.util.xml.DTDEntityResolver.resolveEntity
68,0% - 22.299 ms - 196 inv. org.hibernate.internal.util.xml.DTDEntityResolver.resolveInLocalNamespace
68,0% - 22.299 ms - 196 inv. org.hibernate.internal.util.ConfigHelper.getUserResourceAsStream
68,0% - 22.298 ms - 196 inv. java.lang.ClassLoader.getResourceAsStream


Thank you again for your time and effort.


Top
 Profile  
 
 Post subject: Re: Slow startup
PostPosted: Thu Jan 07, 2016 6:05 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
That could only happen if there is a huge amount of resources on the class-path.
It's strange that it takes as long as fetching it over the network.


Top
 Profile  
 
 Post subject: Re: Slow startup
PostPosted: Thu Jan 07, 2016 6:21 am 
Newbie

Joined: Thu Jan 07, 2016 4:17 am
Posts: 4
Thank you again for your reply!

The problem indeed can be that I run it in an application server (Glassfish) but then it still seems long.

I checked my classpath with JConsole:

Code:
D:\Programs\glassfish3\glassfish/modules/endorsed\javax.annotation.jar;D:\Programs\Java\jdk1.7.0_55\jre\lib\resources.jar;D:\Programs\Java\jdk1.7.0_55\jre\lib\rt.jar;D:\Programs\Java\jdk1.7.0_55\jre\lib\sunrsasign.jar;D:\Programs\Java\jdk1.7.0_55\jre\lib\jsse.jar;D:\Programs\Java\jdk1.7.0_55\jre\lib\jce.jar;D:\Programs\Java\jdk1.7.0_55\jre\lib\charsets.jar;D:\Programs\Java\jdk1.7.0_55\jre\lib\jfr.jar;D:\Programs\Java\jdk1.7.0_55\jre\classes;D:/Programs/glassfish3/glassfish/modules/glassfish.jar;D:/Programs/glassfish3/glassfish/lib/monitor/flashlight-agent.jar


Of course Glassfish uses its own OSGI classloader which also includes our WAR.

Isn't there a way to skip the DTD validation so it does not need to scan this?


Top
 Profile  
 
 Post subject: Re: Slow startup
PostPosted: Thu Jan 07, 2016 7:06 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
I don't think you can disable that because it's needed by the XML parser anyway.

The DTDEntityResolver is deprecated and it was replaced by LocalXmlResourceResolver, which uses StAX for XML parsing.
You could try updating Hibernate and see if it's faster.

I think this is available since 4.3.0.Final.


Top
 Profile  
 
 Post subject: Re: Slow startup
PostPosted: Thu Jan 07, 2016 7:11 am 
Newbie

Joined: Thu Jan 07, 2016 4:17 am
Posts: 4
I'll try updating as soon as possible but we first need to work out some refactorings before we can migrate to hibernate 4.3

Thank you very much for your support!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.