Hibernate Books

All times are UTC - 5 hours [ DST ]

Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Review gnarly bits implementing HV in Karaf/PaxExam
PostPosted: Fri Jun 09, 2017 1:58 pm 

Joined: Mon Aug 07, 2006 6:22 pm
Posts: 57
With help from the docs and the HV maintainers, I've been able to get my HV implementation working in Karaf/PaxExam. However, I'm not really happy about the odd "gnarly bits" that were required to get this working. I'd like to review here all the things I had to do to get this working, in the hopes of clarifying or simplifying part of it.

This is the block that creates the factory:
        factory =
                providerResolver(new HibernateValidatorProviderResolver()).
                messageInterpolator(new ResourceBundleMessageInterpolator(
                        new PlatformResourceBundleLocator(ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES),
                        true, buildExpressionFactory())).

Here's the "buildExpressionFactory" method:
    private ExpressionFactory buildExpressionFactory() {
        ClassLoader oldTccl = Thread.currentThread().getContextClassLoader();
        CompositeClassLoader    ccl = new CompositeClassLoader();
        try {
            return ExpressionFactory.newInstance();
        finally {
            Thread.currentThread().setContextClassLoader( oldTccl );

Here's my simple provider resolver:
public class HibernateValidatorProviderResolver implements ValidationProviderResolver {
    public List<ValidationProvider<?>> getValidationProviders() { return Collections.singletonList(new HibernateValidator()); }

And here's the "CompositeClassLoader":
public class CompositeClassLoader extends ClassLoader {
    private final List<ClassLoader> classLoaders = Collections.synchronizedList(new ArrayList<>());

    public CompositeClassLoader() {
        add(Object.class.getClassLoader()); // bootstrap loader.
        add(getClass().getClassLoader()); // whichever classloader loaded this jar.

    public void add(ClassLoader classLoader) {
        if (classLoader != null) {
            classLoaders.add(0, classLoader);

    public Class<?> loadClass(String name) throws ClassNotFoundException {
        for (Iterator<?> iterator = classLoaders.iterator(); iterator.hasNext();) {
            ClassLoader classLoader = (ClassLoader) iterator.next();
            try {
                return classLoader.loadClass(name);
            } catch (ClassNotFoundException notFound) {
                // ok.. try another one
        // One last try - the context class loader associated with the current thread. Often used in j2ee servers.
        // Note: The contextClassLoader cannot be added to the classLoaders list up front as the thread that constructs
        // XStream is potentially different to thread that uses it.
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        if (contextClassLoader != null) {
            return contextClassLoader.loadClass(name);
        throw new ClassNotFoundException(name);

When I first implemented this and verified the functionality with unit tests, the required setup was much simpler. All of the odd stuff became necessary for running in Karaf/PaxExam.

I really need to understand more about these required pieces, and whether any of this could be simplified. It all works, but I'm concerned that there's too much magic here that I don't understand. I'm particularly concerned about the classloader manipulations, and somewhat less so about the "messageInterpolator" setting.

 Post subject: Re: Review gnarly bits implementing HV in Karaf/PaxExam
PostPosted: Wed Jun 14, 2017 3:16 am 
Hibernate Team
Hibernate Team

Joined: Sat Jan 24, 2009 12:46 pm
Posts: 373

It looks largely alright, only the set-up relating to the expression factory seems overly complex.

The composite class loader shouldn't be needed really, instead the expression factory should be retrievable by just setting the TCCL to your module's class loader (provided you import the javax.el package and the JAR with the coordinates org.glassfish:javax.el:3.0.1-b08 is present as a bundle). In fact it shouldn't even be needed to configure the expression factory yourself at all, i.e. you should be able to omit the entire specification of the message interpolator. HV will then obtain the expression factory itself (again, provided that this EL JAR is present).

I.e. the following should be enough:

Validator validator = Validation.byProvider( HibernateValidator.class )
      .providerResolver( new MyValidationProviderResolver() )
      .externalClassLoader( getClass().getClassLoader() )

If this doesn't work, my guess would be that you have another EL version in use (it used to be two JARs, one for API, one for impl), in which case I'd recommend to try the one above. If you don't need EL at all (because you don't use EL in your validation messages, note though that this is the case for @DecimalMax/@DecimalMin by default), you also could use the org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator which doesn't require the EL dependencies.



Visit my blog at http://musingsofaprogrammingaddict.blogspot.com/

Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 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.