10 Replies Latest reply on Jul 9, 2009 8:26 PM by dmlloyd

    Referencing the bean-deployer namespace from a custom metada

    dmlloyd

      In the jboss-logging.xml deployer that I'm developing, I want to reuse the MC's "AbstractPropertyMetaData" type in order to represent arbitrary properties that can be set on jboss-logging entities. To that end I have this:

      public abstract class AbstractHandlerMetaData {
       (...)
       private List<PropertyMetaData> propertyMetaDataList;
       (...)
       public List<PropertyMetaData> getPropertyMetaDataList() {
       return propertyMetaDataList;
       }
      
       @XmlElementWrapper(name="properties")
       @XmlElement(name="property", type=AbstractPropertyMetaData.class)
       public void setPropertyMetaDataList(final List<PropertyMetaData> propertyMetaDataList) {
       this.propertyMetaDataList = propertyMetaDataList;
       }
      


      But I get a weird error:

      Caused by: org.jboss.xb.binding.JBossXBException: Failed to parse source: The type of the attribute search must be simple or complex with a value adapter: org.jboss.xb.binding.sunday.unmarshalling.TypeBinding@6acbdf6e[null]
      at org.jboss.beans.metadata.plugins.AbstractDependencyValueMetaData.search
      at org.jboss.beans.metadata.plugins.AbstractClassLoaderMetaData.classLoader
      at org.jboss.beans.metadata.plugins.AbstractBeanMetaData.classLoader
      at org.jboss.beans.metadata.plugins.AbstractPropertyMetaData.value
      at org.jboss.logging.metadata.HandlerMetaData.propertyMetaDataList
      at org.jboss.logging.metadata.LoggingMetaData.handlerMetaDataList
      at org.jboss.logging.metadata.LoggingMetaData
       at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBParser.java:203)
       at org.jboss.xb.binding.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:168)
       at org.jboss.xb.util.JBossXBHelper.parse(JBossXBHelper.java:189)
       at org.jboss.xb.util.JBossXBHelper.parse(JBossXBHelper.java:166)
       at org.jboss.deployers.vfs.spi.deployer.SchemaResolverDeployer.parse(SchemaResolverDeployer.java:137)
       at org.jboss.deployers.vfs.spi.deployer.SchemaResolverDeployer.parse(SchemaResolverDeployer.java:121)
       at org.jboss.deployers.vfs.spi.deployer.AbstractVFSParsingDeployer.parseAndInit(AbstractVFSParsingDeployer.java:256)
       at org.jboss.deployers.vfs.spi.deployer.AbstractVFSParsingDeployer.parse(AbstractVFSParsingDeployer.java:188)
       at org.jboss.deployers.spi.deployer.helpers.AbstractParsingDeployerWithOutput.createMetaData(AbstractParsingDeployerWithOutput.java:348)
       ... 33 more
      Caused by: org.jboss.xb.binding.JBossXBRuntimeException: The type of the attribute search must be simple or complex with a value adapter: org.jboss.xb.binding.sunday.unmarshalling.TypeBinding@6acbdf6e[null]
      at org.jboss.beans.metadata.plugins.AbstractDependencyValueMetaData.search
      at org.jboss.beans.metadata.plugins.AbstractClassLoaderMetaData.classLoader
      at org.jboss.beans.metadata.plugins.AbstractBeanMetaData.classLoader
      at org.jboss.beans.metadata.plugins.AbstractPropertyMetaData.value
      at org.jboss.logging.metadata.HandlerMetaData.propertyMetaDataList
      at org.jboss.logging.metadata.LoggingMetaData.handlerMetaDataList
      at org.jboss.logging.metadata.LoggingMetaData
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.rethrowWithLocation(JBossXBNoSchemaBuilder.java:2018)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.createRootElementBinding(JBossXBNoSchemaBuilder.java:346)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.createRootElements(JBossXBNoSchemaBuilder.java:321)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.build(JBossXBNoSchemaBuilder.java:232)
       at org.jboss.xb.builder.JBossXBBuilder.build(JBossXBBuilder.java:291)
       at org.jboss.xb.builder.JBossXBBuilder.build(JBossXBBuilder.java:181)
       at org.jboss.xb.builder.JBossXBBuilder.build(JBossXBBuilder.java:160)
       at org.jboss.xb.binding.resolver.AbstractMutableSchemaResolver.resolve(AbstractMutableSchemaResolver.java:261)
       at org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler.startElement(SundayContentHandler.java:274)
       at org.jboss.xb.binding.parser.sax.SaxJBossXBParser$DelegatingContentHandler.startElement(SaxJBossXBParser.java:401)
       at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
       at org.apache.xerces.impl.xs.XMLSchemaValidator.startElement(Unknown Source)
       at org.apache.xerces.xinclude.XIncludeHandler.startElement(Unknown Source)
       at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
       at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
       at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
       at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
       at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
       at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
       at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
       at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
       at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
       at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBParser.java:199)
       ... 41 more
      Caused by: org.jboss.xb.binding.JBossXBRuntimeException: The type of the attribute search must be simple or complex with a value adapter: org.jboss.xb.binding.sunday.unmarshalling.TypeBinding@6acbdf6e[null]
       at org.jboss.xb.binding.sunday.unmarshalling.AttributeBinding.<init>(AttributeBinding.java:60)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateType(JBossXBNoSchemaBuilder.java:931)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:779)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:767)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateTypeBinding(JBossXBNoSchemaBuilder.java:523)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.resolveTypeBinding(JBossXBNoSchemaBuilder.java:482)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.bindProperty(JBossXBNoSchemaBuilder.java:1684)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateType(JBossXBNoSchemaBuilder.java:1118)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:779)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:767)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateTypeBinding(JBossXBNoSchemaBuilder.java:523)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.resolveTypeBinding(JBossXBNoSchemaBuilder.java:482)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.bindProperty(JBossXBNoSchemaBuilder.java:1684)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateType(JBossXBNoSchemaBuilder.java:1118)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:779)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:767)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateTypeBinding(JBossXBNoSchemaBuilder.java:523)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.resolveTypeBinding(JBossXBNoSchemaBuilder.java:482)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateType(JBossXBNoSchemaBuilder.java:1141)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:779)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:767)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateCollection(JBossXBNoSchemaBuilder.java:710)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateTypeBinding(JBossXBNoSchemaBuilder.java:514)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.resolveTypeBinding(JBossXBNoSchemaBuilder.java:482)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.bindProperty(JBossXBNoSchemaBuilder.java:1684)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateType(JBossXBNoSchemaBuilder.java:1118)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:779)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:767)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateTypeBinding(JBossXBNoSchemaBuilder.java:523)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.resolveTypeBinding(JBossXBNoSchemaBuilder.java:482)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.bindProperty(JBossXBNoSchemaBuilder.java:1684)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateType(JBossXBNoSchemaBuilder.java:1118)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:779)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:767)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateTypeBinding(JBossXBNoSchemaBuilder.java:523)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.resolveTypeBinding(JBossXBNoSchemaBuilder.java:482)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.bindProperty(JBossXBNoSchemaBuilder.java:1684)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateType(JBossXBNoSchemaBuilder.java:1118)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:779)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateBean(JBossXBNoSchemaBuilder.java:767)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateTypeBinding(JBossXBNoSchemaBuilder.java:523)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.resolveTypeBinding(JBossXBNoSchemaBuilder.java:482)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.createElementBinding(JBossXBNoSchemaBuilder.java:361)
       at org.jboss.xb.builder.JBossXBNoSchemaBuilder.createRootElementBinding(JBossXBNoSchemaBuilder.java:341)
       ... 62 more
      


      The weird thing is, this is all part of the bean deployer schema classes which were all registered already, so why is this suddenly a problem when my binding references it? Is there some other thing I need to do to make this work, or can I simply not reuse types in this way?

        • 1. Re: Referencing the bean-deployer namespace from a custom me
          alesj

          I think you're suffering from this issue:
          - https://jira.jboss.org/jira/browse/JBXB-125

          • 2. Re: Referencing the bean-deployer namespace from a custom me
            alesj

            I applied JBXB-125 to appropriate metadata,
            but since this is an api change (moved the classes), this will only be available in Kernel 2.2.x.

            • 3. Re: Referencing the bean-deployer namespace from a custom me
              aloubyansky

              Property bound to an attribute must be of a type that XB knows how to (un)marshal from/to a simple value, e.g. a primitive type (or a wrapper) or String.

              @XmlAttribute(name = "search")
               public void setSearch(SearchInfo search)


              Is none of that. An adapter should be provided that will perform (un)marshalling from/to simple string values.

              • 4. Re: Referencing the bean-deployer namespace from a custom me
                alesj

                 

                "alex.loubyansky@jboss.com" wrote:
                An adapter should be provided that will perform (un)marshalling from/to simple string values.

                This is already there:
                - http://anonsvn.jboss.org/repos/jbossas/projects/microcontainer/branches/Branch_2_0/kernel/src/main/java/org/jboss/beans/metadata/plugins/SearchInfoValueAdapter.java

                I would (still) say he's missing proper package-info.java with duplicated code
                from previous duplicated p-i.java across Kernel project.

                • 5. Re: Referencing the bean-deployer namespace from a custom me
                  dmlloyd

                  Do I need something on package-info.java? Never did before...

                  • 6. Re: Referencing the bean-deployer namespace from a custom me
                    alesj

                     

                    "david.lloyd@jboss.com" wrote:
                    Do I need something on package-info.java? Never did before...

                    Just copy/paste the one from Kernel.
                    And don't forget to change the package. ;-)

                    • 7. Re: Referencing the bean-deployer namespace from a custom me
                      dmlloyd

                      OK, awesome, that worked.

                      One other thing - I have my root element set up to be propOrder={} and modelgroup=CHOICE. I have two properties which are using XmlElements like this:

                       public List<AbstractLoggerMetaData> getLoggerMetaDataList() {
                       return loggerMetaDataList;
                       }
                      
                       @XmlElements({
                       @XmlElement(name = "root-logger", type = RootLoggerMetaData.class),
                       @XmlElement(name = "logger", type = LoggerMetaData.class)
                       })
                       public void setLoggerMetaDataList(final List<AbstractLoggerMetaData> loggerMetaDataList) {
                       this.loggerMetaDataList = loggerMetaDataList;
                       }
                      
                       public List<AbstractHandlerMetaData> getHandlerMetaDataList() {
                       return handlerMetaDataList;
                       }
                      
                       @XmlElements({
                       @XmlElement(name = "handler", type = HandlerMetaData.class),
                       @XmlElement(name = "log4j-appender", type = Log4jAppenderMetaData.class),
                       @XmlElement(name = "console-handler", type = ConsoleHandlerMetaData.class),
                       @XmlElement(name = "file-handler", type = FileHandlerMetaData.class),
                       @XmlElement(name = "periodic-rotating-file-handler", type = PeriodicRotatingFileHandlerMetaData.class),
                       @XmlElement(name = "size-rotating-file-handler", type = SizeRotatingFileHandlerMetaData.class),
                       @XmlElement(name = "async-handler", type = AsyncHandlerMetaData.class),
                       @XmlElement(name = "null-handler", type = NullHandlerMetaData.class)
                       })
                       public void setHandlerMetaDataList(final List<AbstractHandlerMetaData> handlerMetaDataList) {
                       this.handlerMetaDataList = handlerMetaDataList;
                       }
                      
                       public List<InstallHandlerMetaData> getInstallHandlerMetaDataList() {
                       return installHandlerMetaDataList;
                       }
                      
                       @XmlElement(name = "install-handler")
                       public void setInstallHandlerMetaDataList(final List<InstallHandlerMetaData> installHandlerMetaDataList) {
                       this.installHandlerMetaDataList = installHandlerMetaDataList;
                       }
                      


                      But it gives me this error:

                      org.jboss.xb.binding.JBossXBRuntimeException: {urn:jboss:logging:6.0}logger cannot appear in this position. Expected content of {urn:jboss:logging:6.0}logging is choice: {choice}* {choice}* {urn:jboss:logging:6.0}install-handler*
                      


                      I don't think this is correct behavior though. The source XML looks like (comments removed):

                      <logging xmlns="urn:jboss:logging:6.0" xmlns:b="urn:jboss:bean-deployer:2.0">
                       <periodic-rotating-file-handler
                       file-name="${jboss.server.log.dir}/server.log"
                       name="FILE"
                       autoflush="true"
                       append="true"
                       suffix=".yyyy-MM-dd">
                       <error-manager>
                       <only-once/>
                       </error-manager>
                      
                       <formatter>
                       <pattern-formatter pattern="%d %-5p [%c] (%t) %m%n"/>
                       </formatter>
                       </periodic-rotating-file-handler>
                      
                       <console-handler name="CONSOLE" autoflush="true" target="System.out">
                       <error-manager>
                       <only-once/>
                       </error-manager>
                      
                       <level name="INFO"/>
                      
                       <formatter>
                       <pattern-formatter pattern="%d %-5p [%c] (%t) %m%n"/>
                       </formatter>
                       </console-handler>
                      
                       <logger category="org.apache">
                       <level name="INFO"/>
                       </logger>
                      
                       (a bunch more loggers follow)
                      


                      So maybe it's treating the outer choice as maxOccurs=1 or something? Is there something else I need to add?


                      • 8. Re: Referencing the bean-deployer namespace from a custom me
                        dmlloyd

                        Unordered sequence seems to "fix" it, but it doesn't seem correct to me. But for now I am pacified :)

                        • 9. Re: Referencing the bean-deployer namespace from a custom me
                          aloubyansky

                           

                          So maybe it's treating the outer choice as maxOccurs=1 or something?


                          Yes, of course. And IMO that's how it should be. Otherwise, the structures of the bound components/types in Java and XSD are inconsistent. Why don't you use a sequence? What problem does it cause in this case?

                          I have my root element set up to be propOrder={} and modelgroup=CHOICE.

                          If you bind to a choice then propOrder should be removed. propOrder={} is supposed to bind to all.

                          • 10. Re: Referencing the bean-deployer namespace from a custom me
                            dmlloyd

                             

                            "alex.loubyansky@jboss.com" wrote:
                            So maybe it's treating the outer choice as maxOccurs=1 or something?


                            Yes, of course. And IMO that's how it should be. Otherwise, the structures of the bound components/types in Java and XSD are inconsistent. Why don't you use a sequence? What problem does it cause in this case?


                            The problem is that it prevents the user from putting the element in any order. In the schema, all the elements listed in this class are in one "choice"; the only reason they're grouped as they are here is because that's how they're mapped in terms of Java types. So the effect I'm really going for is to have XB take all the XmlElement instances in the class and make one big "choice" out of it with maxOccurs=unbounded.

                            I have my root element set up to be propOrder={} and modelgroup=CHOICE.

                            If you bind to a choice then propOrder should be removed. propOrder={} is supposed to bind to all.