3 Replies Latest reply on Oct 23, 2012 4:29 AM by hardy.ferentschik

    Hibernate Bean Validation not working properly in OSGi env

    thehashcoder

      Hi Everyone,

       

      I'm trying to implement Bean Validation for some of the POJOs which are residing inside bundles using Hibernate Bean Validation. I decided to move the validation logic to a separate bundle (ValidationUtil) so  that all other bundles can access it ( for ex: ValidationClient). But when I try to validate beans which are instantiated inside my client bundles, validation never get fired ( ie my beans bypasses validation though I have assigned wrong values for  the beans).

       

      In my client bundle I have a POJO named DBAuthentication which implements Authentication as shown below.

       

       

      public class DBAuthentication implements Authentication {
      
          @NotNull(message="User Name cannot be null")
          private String userName;
      
          @Min(value=5)
          @NotNull(message="Password cannot be null")
          private String password;
      
          // ---other getters and setters 
      }
      
      
      
      
      

       

      This is what I'm doing in my Client Activator.

       

       

      public void start(BundleContext context) throws Exception {
              System.out.println("Hello World -ValidationClient!!");
      
              try {
                      ValidationUtil validationUtil = new ValidationUtil();     // exported by ValidationUtil bundle
                      Authentication auth = new DBAuthentication();
                      if (validationUtil.isValid(auth)) {
                          System.out.println("Valid");
                      }
              } catch (Exception e) {
                  e.printStackTrace();
              }
      
          }
      

       

      But this always print "Valid".

       

      And this is my ValidationUtil which is inside ValidationUtil bundle.

       

       

      package com.ctl.validation.util;
      
      import java.lang.annotation.Annotation;
      import java.lang.reflect.Field;
      import java.util.ArrayList;
      import java.util.List;
      import java.util.Set;
      import javax.validation.ConstraintViolation;
      import javax.validation.Validation;
      import javax.validation.Validator;
      import javax.validation.ValidatorFactory;
      import javax.validation.groups.Default;
      
       /*
      import com.manessinger.cookbook.exception.ConstraintProperty;
      import com.manessinger.cookbook.exception.ValidationException;
      import com.manessinger.cookbook.exception.ViolationDetail;
       */
      public class ValidationUtil {
      
          // the factory is expensive but thread-safe
          private ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
      
          public boolean isValid(Object obj) throws ValidationException {
      
              System.out.println("in validation util");
              boolean isValid = true;
              List<ViolationDetail> details= null;
      
              /*Field[] fields = obj.getClass().getDeclaredFields();
              System.out.println(fields.length);
              for (Field field : fields) {
                  System.out.println("Field Name "+field.getName());
                  Annotation[] anns = field.getAnnotations();
                  for (Annotation ann : anns) {
                      System.out.println(ann.getClass().getCanonicalName());
                  }
              }*/
              Validator v = factory.getValidator();
      
              Set<ConstraintViolation<Object>> violations = v.validate(obj, Default.class);
              System.out.println(violations.size());
              if (violations != null & !violations.isEmpty()) {
                      isValid = false;
                   details = new ArrayList<ViolationDetail>();
                   for (ConstraintViolation<Object> constrain:violations) {
                       System.out.println("-"+constrain.getMessage());
                       ViolationDetail detail = new ViolationDetail();
                       detail.setAttributeName(constrain.getPropertyPath().toString());
                       detail.setMessage(constrain.getMessage());
                       detail.setViolationType(constrain.getConstraintDescriptor()
                              .getAnnotation().annotationType().getSimpleName());
                       Object invalidValue = constrain.getInvalidValue();
                       detail.setInvalidValue((invalidValue != null ? 
                              invalidValue.toString() : "null"));
                       details.add(detail);
                   }
                   throw new ValidationException(details);
              }
              return isValid;
      
          }
      }
      

       

      Validation is working fine, when I try to validate any beans which are created in side ValidationUtil bundle. Also field.getAnnotations[] is giving me blank array for client bundle beans. I guess this may be because in this case, bean has been loaded by a different class loader. But I couldn't figure out how I can solve this.

       

      I'm attaching the sources for both bundles here. Could any one pls point me to rite direction?

       

      Message was edited by: Ranis MK My Manifest headers look as below. ValidationUtil      Manifest-Version: 1.0     Bundle-ManifestVersion: 2     Bundle-Name: ValidationUtil     Bundle-SymbolicName: ValidationUtil     Bundle-Version: 1.0.0.qualifier     Bundle-Activator: com.ctl.validation.ValidationActivator     Import-Package: org.osgi.framework;version="1.3.0"     Bundle-RequiredExecutionEnvironment: JavaSE-1.6     Bundle-ClassPath: .,hibernate-validator-4.3.0.Final.jar,     jboss-logging-3.1.0.CR2.jar,     validation-api-1.0.0.GA.jar     Export-Package: com.ctl.validation.util      ValidationClient     Manifest-Version: 1.0     Bundle-ManifestVersion: 2     Bundle-Name: ValidationClient     Bundle-SymbolicName: ValidationClient     Bundle-Version: 1.0.0.qualifier     Bundle-Activator: com.ctl.validationclient.ValidationClientActivator     Import-Package: org.osgi.framework;version="1.3.0",     com.ctl.validation.util     Bundle-RequiredExecutionEnvironment: JavaSE-1.6     Bundle-ClassPath: .,validation-api-1.0.0.GA.jar     Export-Package: com.ctl.validationclient.model      ( I have copied all the required jars into the bundle just to make the set up simple ).

        • 1. Re: Hibernate Bean Validation not working properly in OSGi env
          hardy.ferentschik

          I am by no means an OSGi expert, but are you sure that your client bundle properly export the beans you want to validate? Do you not have to use something like DynamicImport-Package in the ValidationUtil manifest in order to allow this module to use reflection on the beans to validate? How do your OSGi headers look like?

          • 2. Re: Hibernate Bean Validation not working properly in OSGi env
            thehashcoder

            Hi Hardy,Thanks for looking into this.

             

            Is it really needed to export the client beans which I am validating?I think I need not do that and I haven't got any ClassNotFoundExceptions so far.

            I tried using Dynamic-Import also , but still it behaves the same.

             

            My Manifest headers look as below.

             

            ValidationUtil

             

            Manifest-Version: 1.0

            Bundle-ManifestVersion: 2

            Bundle-Name: ValidationUtil

            Bundle-SymbolicName: ValidationUtil

            Bundle-Version: 1.0.0.qualifier

            Bundle-Activator: com.ctl.validation.ValidationActivator

            Import-Package: org.osgi.framework;version="1.3.0"

            Bundle-RequiredExecutionEnvironment: JavaSE-1.6

            Bundle-ClassPath: .,hibernate-validator-4.3.0.Final.jar,

            jboss-logging-3.1.0.CR2.jar,

            validation-api-1.0.0.GA.jar

            Export-Package: com.ctl.validation.util

             

             

            ValidationClient

             

            Manifest-Version: 1.0

            Bundle-ManifestVersion: 2

            Bundle-Name: ValidationClient

            Bundle-SymbolicName: ValidationClient

            Bundle-Version: 1.0.0.qualifier

            Bundle-Activator: com.ctl.validationclient.ValidationClientActivator

            Import-Package: org.osgi.framework;version="1.3.0",

            com.ctl.validation.util

            Bundle-RequiredExecutionEnvironment: JavaSE-1.6

            Bundle-ClassPath: .,validation-api-1.0.0.GA.jar

            Export-Package: com.ctl.validationclient.model

             

             

            ( I have copied all the required jars into the bundle just to make the set up simple ).

             

            Thanks

            Ranis MK

            • 3. Re: Hibernate Bean Validation not working properly in OSGi env
              hardy.ferentschik

              Is it really needed to export the client beans which I am validating?I think I need not do that and I haven't got any ClassNotFoundExceptions so far.

               

              I would have thought so, but I am by no means a OSGi expert. Given that "normal" reflection does not work either I think the validation is not the actual problem here. Given that the constraints are not visible validation will always succeed. I think that's the main issue here.

               

              Another thought, do you really think that is a good idea from a design point of view to pass the entities to validate to another bundle. I would expect that you are "asking" for a Validator instance and do your validation in the client module.