[
http://opensource.atlassian.com/projects/hibernate/browse/HV-363?page=com...
]
Sanjeeb Sahoo commented on HV-363:
----------------------------------
The rules for classloading is not that complicated in a container environment. If a
framework or library wants to load user domain classes, then it should use Thread's
context classloader; if it wants to load classes from its own package, it should use
Class.forName. This is pretty well defined in EE platform spec:
/EE.8.2.5 Dynamic Class Loading
Libraries that dynamically load classes must consider the class loading environment
of a Java EE application. Libraries will often be loaded by a class loader that is a
parent class loader of the class loader that is used to load application classes. A
library that only needs to dynamically load classes provided by the library itself can
safely use the Class method forName. However, libraries that need to dynamically
load classes that have been provided as a part of the application need to use the
context class loader to load the classes. /
In this case, one HV class is loading class from the same HV package using Thread's
context class loader! So far, there has been no satisfactory answer to why Class.forName
is insufficient in this case. Imagine Thread's context classloader loads a different
version of Hibernate Validator.
HV uses Thread's context class loader to load internal
implementation classes
-----------------------------------------------------------------------------
Key: HV-363
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HV-363
Project: Hibernate Validator
Issue Type: Bug
Components: engine
Reporter: Sanjeeb Sahoo
Assignee: Hardy Ferentschik
Priority: Blocker
{{org.hibernate.validator.engine.resolver.DefaultTraversableResolver}} uses Thread's
context class loader to load {{JPA_AWARE_TRAVERSABLE_RESOLVER_CLASS_NAME}}, which is
{{org.hibernate.validator.engine.resolver.JPATraversableResolver}}. Why? Since one
implementation class is looking for another implementation class, should it not use
{{getClass().getClassLoader()}} instead? The relevant code is given below:
{code}
private void detectJPA() {
try {
loadClass( PERSISTENCE_UTIL_CLASS_NAME, this.getClass() );
log.debug( "Found {} on classpath.", PERSISTENCE_UTIL_CLASS_NAME );
}
catch ( ValidationException e ) {
log.debug(
"Cannot find {} on classpath. All properties will per default be
traversable.",
PERSISTENCE_UTIL_CLASS_NAME
);
return;
}
try {
@SuppressWarnings( "unchecked" )
Class<? extends TraversableResolver> jpaAwareResolverClass = (Class<? extends
TraversableResolver>)
loadClass(JPA_AWARE_TRAVERSABLE_RESOLVER_CLASS_NAME, this.getClass() );
NewInstance<? extends TraversableResolver> newInstance = NewInstance.action(
jpaAwareResolverClass, "" );
if ( System.getSecurityManager() != null ) {
jpaTraversableResolver = AccessController.doPrivileged( newInstance );
}
else {
jpaTraversableResolver = newInstance.run();
}
log.info(
"Instantiated an instance of {}.",
JPA_AWARE_TRAVERSABLE_RESOLVER_CLASS_NAME
);
}
catch ( ValidationException e ) {
log.info(
"Unable to load or instanciate JPA aware resolver {}. All properties will per
default be traversable.",
JPA_AWARE_TRAVERSABLE_RESOLVER_CLASS_NAME
);
}
}
{code}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira