10 Replies Latest reply on Jun 4, 2009 8:43 AM by aloubyansky

    Marshalling an AbstractKernelDeployment

    flavia.rainone

      I've been trying to marshal an AbstractKernelDeployment without success:

      AbstractKernelDeployment deployment = new AbstractKernelDeployment();
       AbstractBeanMetaData beanMetaData = new AbstractBeanMetaData();
       beanMetaData.setBean(Test.class.getName());
       beanMetaData.setName("test");
       List<BeanMetaDataFactory> beanFactories = new ArrayList<BeanMetaDataFactory>();
       beanFactories.add(beanMetaData);
       deployment.setBeanFactories(beanFactories);
       MarshallerImpl marshaller = new MarshallerImpl();
       SchemaBindingResolver resolver = SingletonSchemaResolverFactory.getInstance().getSchemaBindingResolver();
       marshaller.setSchemaResolver(resolver);
       StringWriter writer = new StringWriter();
      
       URL url = Test.class.getClassLoader().getResource("schema/bean-deployer_2_0.xsd");
      
       marshaller.marshal(url.toString(), null, deployment, writer);


      I'm getting this exception:

      Exception in thread "main" org.jboss.xb.binding.JBossXBRuntimeException: Missing value for the required attribute bean of element {urn:jboss:bean-deployer:2.0}lazy
       at org.jboss.xb.binding.sunday.marshalling.DefaultAttributeMarshaller.marshalValue(DefaultAttributeMarshaller.java:89)
       at org.jboss.xb.binding.sunday.marshalling.AbstractAttributeMarshaller.marshal(AbstractAttributeMarshaller.java:39)
       at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalComplexType(MarshallerImpl.java:547)
       at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalElementType(MarshallerImpl.java:430)
       at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalElement(MarshallerImpl.java:329)
       at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalElementOccurence(MarshallerImpl.java:309)
       at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshallInternal(MarshallerImpl.java:215)
       at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshal(MarshallerImpl.java:150)
       at org.jboss.microcontainer.tools.Test.main(Test.java:69)


      Debugging the code, I see that MarshallerImpl (lines 211-216) marshals the deployment by iterating through the ElementBindings and marshalling the ocurrences of each of one those elements:

      while(elements.hasNext())
       {
       ParticleBinding element = elements.next();
       ctx.particle = element;
       marshalElementOccurence((ElementBinding) element.getTerm(), root, true, true);
       }


      It seems that at some point, between the marshalElementOcurrence() call and the execution of marshalComplexType(), MarshallerImpl assumes that the element at the stack is a lazy element instead of a deployment element. Given that it isn't, MarshallerImpl fails to find the value of the mandatory bean attribute of lazy and throws the exception above.

      Taking a look at XsdBinder (lines 476-483), I see that it binds the schema elements with a minOcurrences of 1:

      XSNamedMap elements = model.getComponents(XSConstants.ELEMENT_DECLARATION);
       if (trace)
       log.trace("Model elements: " + types.getLength());
       for(int i = 0; i < elements.getLength(); ++i)
       {
       XSElementDeclaration element = (XSElementDeclaration)elements.item(i);
       bindElement(element, 1, 0, false);
       }


      I'm not sure if this has something to do with the problem or not, but it looks weird from my point of view.

      So, am I doing this the wrong way? Or is this a bug?

        • 1. Re: Marshalling an AbstractKernelDeployment
          aloubyansky

          First of all, you should be using marshal method which takes SchemaBinding argument.

          SchemaBinding for AbstractKernelDeployment is created by parsing JAXB/JBossXB annotations, not by parsing the XSD (this XSD doesn't contain any binding information).

          You'll need to use one of the build methods of org.jboss.xb.builder.JBossXBBuilder to create SchemaBinding from annotated Java classes.

          • 2. Re: Marshalling an AbstractKernelDeployment
            flavia.rainone

            Alex,

            I'm now using the SchemaBinding as you suggested:

            SchemaBinding binding = JBossXBBuilder.build(AbstractKernelDeployment.class);
            marshaller.marshal(binding, null, deployment, writer);


            It still looks like I'm missing something:

            Exception in thread "main" org.jboss.xb.binding.JBossXBRuntimeException: Failed to marshal wildcard: neither class mapping was found for class org.jboss.kernel.plugins.deployment.AbstractKernelDeployment@19267322 (toString: AbstractKernelDeployment@125fefa{name=null installed=false beanFactories=[AbstractBeanMetaData@186df0f{name=test bean=org.jboss.microcontainer.tools.Test properties= constructor=null autowireCandidate=true}]}) nor marshaller for unresolved classes was setup.
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalWildcard(MarshallerImpl.java:833)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalWildcardOccurence(MarshallerImpl.java:792)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalParticle(MarshallerImpl.java:745)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalModelGroupSequence(MarshallerImpl.java:970)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalModelGroup(MarshallerImpl.java:910)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalParticle(MarshallerImpl.java:656)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalModelGroupSequence(MarshallerImpl.java:970)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalModelGroup(MarshallerImpl.java:910)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalParticle(MarshallerImpl.java:656)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalComplexType(MarshallerImpl.java:619)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalElementType(MarshallerImpl.java:430)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalElement(MarshallerImpl.java:329)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalElementOccurence(MarshallerImpl.java:309)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshallInternal(MarshallerImpl.java:215)
             at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshal(MarshallerImpl.java:157)
             at org.jboss.microcontainer.tools.Test.main(Test.java:79)
            


            Any thoughts?

            • 3. Re: Marshalling an AbstractKernelDeployment
              alesj

              I think you should use AbstractKernelDeployment10 class.

              • 4. Re: Marshalling an AbstractKernelDeployment
                flavia.rainone

                 

                "Ales" wrote:
                I think you should use AbstractKernelDeployment10 class.

                Unfortunately, I get the same exception with AbstractKernelDeployment10:

                Exception in thread "main" org.jboss.xb.binding.JBossXBRuntimeException: Failed to marshal wildcard: neither class mapping was found for class org.jboss.kernel.plugins.deployment.AbstractKernelDeployment10@15594486 (toString: AbstractKernelDeployment10@edf3f6{name=null installed=false beanFactories=[AbstractBeanMetaData@2bc3f5{name=test bean=org.jboss.microcontainer.tools.Test3 properties= constructor=null autowireCandidate=true}]}) nor marshaller for unresolved classes was setup.
                 at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalWildcard(MarshallerImpl.java:833)
                 at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalWildcardOccurence(MarshallerImpl.java:792)
                 at org.jboss.xb.binding.sunday.marshalling.MarshallerImpl.marshalParticle(MarshallerImpl.java:745)
                ...


                • 5. Re: Marshalling an AbstractKernelDeployment
                  aloubyansky

                  Yes, I see it. I am running your testcase. You are not doing anything wrong. The marshaller implementation does though :)

                  As I told you, marshalling was implemented to cover (limited) contract with JBossWS. But has not been used by others.
                  I am going to look into this and let you know how it goes.

                  • 6. Re: Marshalling an AbstractKernelDeployment
                    flavia.rainone

                     

                    "Alex" wrote:
                    I am going to look into this and let you know how it goes.

                    Thanks!

                    "Alex" wrote:
                    As I told you, marshalling was implemented to cover (limited) contract with JBossWS. But has not been used by others.


                    I'm working on a tool that converts service.xml files into beans.xml files.

                    http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4230944#4230944

                    IMO, the simplest way of doing this tool is converting the service meta data into bean meta data and using JBossXB to generate the resulting XML. I also thought of XLST, but AFAIK that wouldn't allow querying input from the user during the convertion process.

                    If you think of a better way to do this, let me know.

                    • 7. Re: Marshalling an AbstractKernelDeployment
                      aloubyansky

                      If I wanted to do it quick, I would go with XSLT. But if the goal is to have a proper tool then probably doing it through JAXB/JBossXB is a better choice (mapping Java APIs maybe an advantage).

                      • 8. Re: Marshalling an AbstractKernelDeployment
                        aloubyansky

                        Yes, marshalling has to be re-written. A few hacks can be added to make some basic cases work. But MC metadata uses quite sophisticated binding tricks. Unmarshalling is way ahead of marshalling in terms of binding power.

                        Current marshalling is based on binding with XsdBinder and uses different (and more primitive compared to unmarshalling) binding metadata. So, basically, it has to be re-written.

                        But if we want to be able to marshal MC metadata or any other metadata with XB we have no choice. I can start working on it if we decide this is what we want to do.

                        • 9. Re: Marshalling an AbstractKernelDeployment
                          flavia.rainone

                           

                          "alex.loubyansky@jboss.com" wrote:
                          If I wanted to do it quick, I would go with XSLT. But if the goal is to have a proper tool then probably doing it through JAXB/JBossXB is a better choice (mapping Java APIs maybe an advantage).

                          Can I marshal the KernelDeployment with JAXB solely?
                          If I can't, then I think I'll generate the xml myself. This is cheaper then having you fix marshalling at JBossXB, and I don't see the point of doing this just for one use case.

                          • 10. Re: Marshalling an AbstractKernelDeployment
                            aloubyansky

                            I don't think JAXB will be easier since MC classes use JBXB-specific binding features which make binding simpler than plain JAXB.
                            So, at the moment, XSLT seems like a cheaper option.
                            I'll still talk to Jason to see if we want to have marshalling binding features match the unmarshalling ones.