You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Federico Sajeva <th...@gmail.com> on 2021/04/07 10:34:02 UTC

camel-quarkus-dozer. Error when running native executable

Hello there,

I have an application based on camel-quarkus that (1) split xml
payloads using StAX and JAXB, (2) use Dozer to map each record to
domain objects annotated with protostream and (3) put each domain
object into an Infinispan remote cache.
JAXB classes are generated through xjc from a schema delivered by a
central Institution.
So far so good; everything works fine in non-native mode.
Problems come out when I try to run the native executable.
I get the following Exception during the mapping process and in
particular mapping a java.util.Date field.
For the record Protostream supports just Date and Instant for time fields.

    Dest field type: java.util.Date:
com.github.dozermapper.core.converters.ConversionException:
java.lang.NoSuchMethodException: java.util.Date.<init>(long)
    at com.github.dozermapper.core.converters.DateConverter.convert(DateConverter.java:102)
    at com.github.dozermapper.core.converters.PrimitiveOrWrapperConverter.convert(PrimitiveOrWrapperConverter.java:84)
    at com.github.dozermapper.core.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:496)
    at com.github.dozermapper.core.MappingProcessor.mapFromFieldMap(MappingProcessor.java:404)
    at com.github.dozermapper.core.MappingProcessor.mapField(MappingProcessor.java:354)
    at com.github.dozermapper.core.MappingProcessor.map(MappingProcessor.java:314)
    at com.github.dozermapper.core.MappingProcessor.mapToDestObject(MappingProcessor.java:263)
    at com.github.dozermapper.core.MappingProcessor.createByCreationDirectiveAndMap(MappingProcessor.java:236)
    at com.github.dozermapper.core.MappingProcessor.mapGeneral(MappingProcessor.java:209)
    ...

Hereafter an excerpt of the route managing the application logic; I've
used object names of the common Microsoft examples available in
Internet (Books/Book xsd and xml)

@ApplicationScoped
public class FileLoadRouter extends RouteBuilder {

    @ConfigProperty(name = "code-with-quarkus.inputFolder")
    String inputFolder;


    @Override
    public void configure() throws Exception {

        DataFormat jaxb = new
JaxbDataFormat(JAXBContext.newInstance(ObjectFactory.class));

        from(String.format("file:%s?noop=true&moveFailed=${file:name}.error&include=.*.xml",
inputFolder))
                .streamCaching()
                .log("Starting file process ${file:onlyname} " + "${file:size}")
                .split().tokenizeXML("book", "*").streaming()
                .unmarshal(jaxb)

.to("dozer:bookMapping?mappingFile=bookMapping.xml&targetModel=org.acme.dto.Book")
                .bean(infinispanService, "load")
                .choice()
                    .when(header(Exchange.SPLIT_COMPLETE))
                        .log("File ${file:onlyname} completed")
                .endChoice();
    }
}

Here the mapping file (bookMapping.xml):

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozermapper.github.io/schema/bean-mapping"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping
            https://dozermapper.github.io/schema/bean-mapping.xsd">
    <mapping type="one-way" wildcard="false">
      <class-a>org.acme.jaxb.BooksForm</class-a>
      <class-b>org.acme.dto.Book</class-b>
      <field>
        <a>book[0].id</a>
        <b>key</b>
      </field>
      <field>
        <a>book[0].author</a>
        <b>author</b>
      </field>
      <field>
        <a>book[0].pubDate</a>
        <b>publicationDate</b>
      </field>
      <field>
        <a>book[0].price</a>
        <b>price</b>
      </field>
    </mapping>
  </mappings>


I've tried to hard-code the mapping in a small part of the application
and everything works fine even running the native executable. The same
if I use Instant instead of Date. Unfortunately it's a complex
microservice and I don't want to change the definition, said that
Instant should be definitely meaningless for dates without seconds

Am I missing something in Dozer (or Quarkus) configuration for
java.util.Date fields? Or is it a bug related to native compilation
for camel-quarkus-dozer?

Many thanks

Re: camel-quarkus-dozer. Error when running native executable

Posted by Zheng Feng <zf...@redhat.com>.
Hi Federico,

I can reproduce this issue with the camel-quarkus-dozer and please raise an
issue on https://github.com/apache/camel-quarkus/issues. I think it should
be fixed in the camel-quarkus.

Thanks,
Zheng Feng

On Wed, Apr 7, 2021 at 10:22 PM Federico Sajeva <th...@gmail.com>
wrote:

> Thank you Alexandre,
> it worked like a charm with both the ways suggested (annotated dummy
> class or reflection-config.json file).
> Never thought I had to explicitly declare for reflection a pretty old
> (and possibly obsolete) class like java.util.Date.
> But as I said in my question java.util.Date and java.time.Instant are
> the only types available in protostream schema for time objects. And
> honestly Instant is definitely meaningless for informations without
> seconds like starting or ending validity dates
> Anyway it did the trick, you made my day!
> Cheers mate
>
>
> Il giorno mer 7 apr 2021 alle ore 15:16 Alexandre Gallice
> <al...@gmail.com> ha scritto:
> >
> > Hi Federico,
> >
> >   From the logs, it looks that "java.util.Date" class should be
> registered
> > for reflection.
> > There are multiple solutions for such cases as described here:
> >
> https://quarkus.io/guides/writing-native-applications-tips#registering-for-reflection
> > .
> >
> >   So, I would first try to register the class manually. And maybe open a
> > ticket (https://github.com/apache/camel-quarkus/issues/new)
> > if there are rationales that this class should not be manual registered
> by
> > developer, but more automatically registered via camel-quarkus-dozer
> > extension.
> >
> > hth,
> > Alex
> >
> >
> >
> >
> > On Wed, Apr 7, 2021 at 12:34 PM Federico Sajeva <th...@gmail.com>
> > wrote:
> >
> > > Hello there,
> > >
> > > I have an application based on camel-quarkus that (1) split xml
> > > payloads using StAX and JAXB, (2) use Dozer to map each record to
> > > domain objects annotated with protostream and (3) put each domain
> > > object into an Infinispan remote cache.
> > > JAXB classes are generated through xjc from a schema delivered by a
> > > central Institution.
> > > So far so good; everything works fine in non-native mode.
> > > Problems come out when I try to run the native executable.
> > > I get the following Exception during the mapping process and in
> > > particular mapping a java.util.Date field.
> > > For the record Protostream supports just Date and Instant for time
> fields.
> > >
> > >     Dest field type: java.util.Date:
> > > com.github.dozermapper.core.converters.ConversionException:
> > > java.lang.NoSuchMethodException: java.util.Date.<init>(long)
> > >     at
> > >
> com.github.dozermapper.core.converters.DateConverter.convert(DateConverter.java:102)
> > >     at
> > >
> com.github.dozermapper.core.converters.PrimitiveOrWrapperConverter.convert(PrimitiveOrWrapperConverter.java:84)
> > >     at
> > >
> com.github.dozermapper.core.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:496)
> > >     at
> > >
> com.github.dozermapper.core.MappingProcessor.mapFromFieldMap(MappingProcessor.java:404)
> > >     at
> > >
> com.github.dozermapper.core.MappingProcessor.mapField(MappingProcessor.java:354)
> > >     at
> > >
> com.github.dozermapper.core.MappingProcessor.map(MappingProcessor.java:314)
> > >     at
> > >
> com.github.dozermapper.core.MappingProcessor.mapToDestObject(MappingProcessor.java:263)
> > >     at
> > >
> com.github.dozermapper.core.MappingProcessor.createByCreationDirectiveAndMap(MappingProcessor.java:236)
> > >     at
> > >
> com.github.dozermapper.core.MappingProcessor.mapGeneral(MappingProcessor.java:209)
> > >     ...
> > >
> > > Hereafter an excerpt of the route managing the application logic; I've
> > > used object names of the common Microsoft examples available in
> > > Internet (Books/Book xsd and xml)
> > >
> > > @ApplicationScoped
> > > public class FileLoadRouter extends RouteBuilder {
> > >
> > >     @ConfigProperty(name = "code-with-quarkus.inputFolder")
> > >     String inputFolder;
> > >
> > >
> > >     @Override
> > >     public void configure() throws Exception {
> > >
> > >         DataFormat jaxb = new
> > > JaxbDataFormat(JAXBContext.newInstance(ObjectFactory.class));
> > >
> > >
> > >
> from(String.format("file:%s?noop=true&moveFailed=${file:name}.error&include=.*.xml",
> > > inputFolder))
> > >                 .streamCaching()
> > >                 .log("Starting file process ${file:onlyname} " +
> > > "${file:size}")
> > >                 .split().tokenizeXML("book", "*").streaming()
> > >                 .unmarshal(jaxb)
> > >
> > >
> > >
> .to("dozer:bookMapping?mappingFile=bookMapping.xml&targetModel=org.acme.dto.Book")
> > >                 .bean(infinispanService, "load")
> > >                 .choice()
> > >                     .when(header(Exchange.SPLIT_COMPLETE))
> > >                         .log("File ${file:onlyname} completed")
> > >                 .endChoice();
> > >     }
> > > }
> > >
> > > Here the mapping file (bookMapping.xml):
> > >
> > > <?xml version="1.0" encoding="UTF-8"?>
> > > <mappings xmlns="http://dozermapper.github.io/schema/bean-mapping"
> > >           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> > >           xsi:schemaLocation="
> > > http://dozermapper.github.io/schema/bean-mapping
> > >             https://dozermapper.github.io/schema/bean-mapping.xsd">
> > >     <mapping type="one-way" wildcard="false">
> > >       <class-a>org.acme.jaxb.BooksForm</class-a>
> > >       <class-b>org.acme.dto.Book</class-b>
> > >       <field>
> > >         <a>book[0].id</a>
> > >         <b>key</b>
> > >       </field>
> > >       <field>
> > >         <a>book[0].author</a>
> > >         <b>author</b>
> > >       </field>
> > >       <field>
> > >         <a>book[0].pubDate</a>
> > >         <b>publicationDate</b>
> > >       </field>
> > >       <field>
> > >         <a>book[0].price</a>
> > >         <b>price</b>
> > >       </field>
> > >     </mapping>
> > >   </mappings>
> > >
> > >
> > > I've tried to hard-code the mapping in a small part of the application
> > > and everything works fine even running the native executable. The same
> > > if I use Instant instead of Date. Unfortunately it's a complex
> > > microservice and I don't want to change the definition, said that
> > > Instant should be definitely meaningless for dates without seconds
> > >
> > > Am I missing something in Dozer (or Quarkus) configuration for
> > > java.util.Date fields? Or is it a bug related to native compilation
> > > for camel-quarkus-dozer?
> > >
> > > Many thanks
> > >
>
>

Re: camel-quarkus-dozer. Error when running native executable

Posted by Federico Sajeva <th...@gmail.com>.
Thank you Alexandre,
it worked like a charm with both the ways suggested (annotated dummy
class or reflection-config.json file).
Never thought I had to explicitly declare for reflection a pretty old
(and possibly obsolete) class like java.util.Date.
But as I said in my question java.util.Date and java.time.Instant are
the only types available in protostream schema for time objects. And
honestly Instant is definitely meaningless for informations without
seconds like starting or ending validity dates
Anyway it did the trick, you made my day!
Cheers mate


Il giorno mer 7 apr 2021 alle ore 15:16 Alexandre Gallice
<al...@gmail.com> ha scritto:
>
> Hi Federico,
>
>   From the logs, it looks that "java.util.Date" class should be registered
> for reflection.
> There are multiple solutions for such cases as described here:
> https://quarkus.io/guides/writing-native-applications-tips#registering-for-reflection
> .
>
>   So, I would first try to register the class manually. And maybe open a
> ticket (https://github.com/apache/camel-quarkus/issues/new)
> if there are rationales that this class should not be manual registered by
> developer, but more automatically registered via camel-quarkus-dozer
> extension.
>
> hth,
> Alex
>
>
>
>
> On Wed, Apr 7, 2021 at 12:34 PM Federico Sajeva <th...@gmail.com>
> wrote:
>
> > Hello there,
> >
> > I have an application based on camel-quarkus that (1) split xml
> > payloads using StAX and JAXB, (2) use Dozer to map each record to
> > domain objects annotated with protostream and (3) put each domain
> > object into an Infinispan remote cache.
> > JAXB classes are generated through xjc from a schema delivered by a
> > central Institution.
> > So far so good; everything works fine in non-native mode.
> > Problems come out when I try to run the native executable.
> > I get the following Exception during the mapping process and in
> > particular mapping a java.util.Date field.
> > For the record Protostream supports just Date and Instant for time fields.
> >
> >     Dest field type: java.util.Date:
> > com.github.dozermapper.core.converters.ConversionException:
> > java.lang.NoSuchMethodException: java.util.Date.<init>(long)
> >     at
> > com.github.dozermapper.core.converters.DateConverter.convert(DateConverter.java:102)
> >     at
> > com.github.dozermapper.core.converters.PrimitiveOrWrapperConverter.convert(PrimitiveOrWrapperConverter.java:84)
> >     at
> > com.github.dozermapper.core.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:496)
> >     at
> > com.github.dozermapper.core.MappingProcessor.mapFromFieldMap(MappingProcessor.java:404)
> >     at
> > com.github.dozermapper.core.MappingProcessor.mapField(MappingProcessor.java:354)
> >     at
> > com.github.dozermapper.core.MappingProcessor.map(MappingProcessor.java:314)
> >     at
> > com.github.dozermapper.core.MappingProcessor.mapToDestObject(MappingProcessor.java:263)
> >     at
> > com.github.dozermapper.core.MappingProcessor.createByCreationDirectiveAndMap(MappingProcessor.java:236)
> >     at
> > com.github.dozermapper.core.MappingProcessor.mapGeneral(MappingProcessor.java:209)
> >     ...
> >
> > Hereafter an excerpt of the route managing the application logic; I've
> > used object names of the common Microsoft examples available in
> > Internet (Books/Book xsd and xml)
> >
> > @ApplicationScoped
> > public class FileLoadRouter extends RouteBuilder {
> >
> >     @ConfigProperty(name = "code-with-quarkus.inputFolder")
> >     String inputFolder;
> >
> >
> >     @Override
> >     public void configure() throws Exception {
> >
> >         DataFormat jaxb = new
> > JaxbDataFormat(JAXBContext.newInstance(ObjectFactory.class));
> >
> >
> > from(String.format("file:%s?noop=true&moveFailed=${file:name}.error&include=.*.xml",
> > inputFolder))
> >                 .streamCaching()
> >                 .log("Starting file process ${file:onlyname} " +
> > "${file:size}")
> >                 .split().tokenizeXML("book", "*").streaming()
> >                 .unmarshal(jaxb)
> >
> >
> > .to("dozer:bookMapping?mappingFile=bookMapping.xml&targetModel=org.acme.dto.Book")
> >                 .bean(infinispanService, "load")
> >                 .choice()
> >                     .when(header(Exchange.SPLIT_COMPLETE))
> >                         .log("File ${file:onlyname} completed")
> >                 .endChoice();
> >     }
> > }
> >
> > Here the mapping file (bookMapping.xml):
> >
> > <?xml version="1.0" encoding="UTF-8"?>
> > <mappings xmlns="http://dozermapper.github.io/schema/bean-mapping"
> >           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> >           xsi:schemaLocation="
> > http://dozermapper.github.io/schema/bean-mapping
> >             https://dozermapper.github.io/schema/bean-mapping.xsd">
> >     <mapping type="one-way" wildcard="false">
> >       <class-a>org.acme.jaxb.BooksForm</class-a>
> >       <class-b>org.acme.dto.Book</class-b>
> >       <field>
> >         <a>book[0].id</a>
> >         <b>key</b>
> >       </field>
> >       <field>
> >         <a>book[0].author</a>
> >         <b>author</b>
> >       </field>
> >       <field>
> >         <a>book[0].pubDate</a>
> >         <b>publicationDate</b>
> >       </field>
> >       <field>
> >         <a>book[0].price</a>
> >         <b>price</b>
> >       </field>
> >     </mapping>
> >   </mappings>
> >
> >
> > I've tried to hard-code the mapping in a small part of the application
> > and everything works fine even running the native executable. The same
> > if I use Instant instead of Date. Unfortunately it's a complex
> > microservice and I don't want to change the definition, said that
> > Instant should be definitely meaningless for dates without seconds
> >
> > Am I missing something in Dozer (or Quarkus) configuration for
> > java.util.Date fields? Or is it a bug related to native compilation
> > for camel-quarkus-dozer?
> >
> > Many thanks
> >

Re: camel-quarkus-dozer. Error when running native executable

Posted by Alexandre Gallice <al...@gmail.com>.
Hi Federico,

  From the logs, it looks that "java.util.Date" class should be registered
for reflection.
There are multiple solutions for such cases as described here:
https://quarkus.io/guides/writing-native-applications-tips#registering-for-reflection
.

  So, I would first try to register the class manually. And maybe open a
ticket (https://github.com/apache/camel-quarkus/issues/new)
if there are rationales that this class should not be manual registered by
developer, but more automatically registered via camel-quarkus-dozer
extension.

hth,
Alex




On Wed, Apr 7, 2021 at 12:34 PM Federico Sajeva <th...@gmail.com>
wrote:

> Hello there,
>
> I have an application based on camel-quarkus that (1) split xml
> payloads using StAX and JAXB, (2) use Dozer to map each record to
> domain objects annotated with protostream and (3) put each domain
> object into an Infinispan remote cache.
> JAXB classes are generated through xjc from a schema delivered by a
> central Institution.
> So far so good; everything works fine in non-native mode.
> Problems come out when I try to run the native executable.
> I get the following Exception during the mapping process and in
> particular mapping a java.util.Date field.
> For the record Protostream supports just Date and Instant for time fields.
>
>     Dest field type: java.util.Date:
> com.github.dozermapper.core.converters.ConversionException:
> java.lang.NoSuchMethodException: java.util.Date.<init>(long)
>     at
> com.github.dozermapper.core.converters.DateConverter.convert(DateConverter.java:102)
>     at
> com.github.dozermapper.core.converters.PrimitiveOrWrapperConverter.convert(PrimitiveOrWrapperConverter.java:84)
>     at
> com.github.dozermapper.core.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:496)
>     at
> com.github.dozermapper.core.MappingProcessor.mapFromFieldMap(MappingProcessor.java:404)
>     at
> com.github.dozermapper.core.MappingProcessor.mapField(MappingProcessor.java:354)
>     at
> com.github.dozermapper.core.MappingProcessor.map(MappingProcessor.java:314)
>     at
> com.github.dozermapper.core.MappingProcessor.mapToDestObject(MappingProcessor.java:263)
>     at
> com.github.dozermapper.core.MappingProcessor.createByCreationDirectiveAndMap(MappingProcessor.java:236)
>     at
> com.github.dozermapper.core.MappingProcessor.mapGeneral(MappingProcessor.java:209)
>     ...
>
> Hereafter an excerpt of the route managing the application logic; I've
> used object names of the common Microsoft examples available in
> Internet (Books/Book xsd and xml)
>
> @ApplicationScoped
> public class FileLoadRouter extends RouteBuilder {
>
>     @ConfigProperty(name = "code-with-quarkus.inputFolder")
>     String inputFolder;
>
>
>     @Override
>     public void configure() throws Exception {
>
>         DataFormat jaxb = new
> JaxbDataFormat(JAXBContext.newInstance(ObjectFactory.class));
>
>
> from(String.format("file:%s?noop=true&moveFailed=${file:name}.error&include=.*.xml",
> inputFolder))
>                 .streamCaching()
>                 .log("Starting file process ${file:onlyname} " +
> "${file:size}")
>                 .split().tokenizeXML("book", "*").streaming()
>                 .unmarshal(jaxb)
>
>
> .to("dozer:bookMapping?mappingFile=bookMapping.xml&targetModel=org.acme.dto.Book")
>                 .bean(infinispanService, "load")
>                 .choice()
>                     .when(header(Exchange.SPLIT_COMPLETE))
>                         .log("File ${file:onlyname} completed")
>                 .endChoice();
>     }
> }
>
> Here the mapping file (bookMapping.xml):
>
> <?xml version="1.0" encoding="UTF-8"?>
> <mappings xmlns="http://dozermapper.github.io/schema/bean-mapping"
>           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>           xsi:schemaLocation="
> http://dozermapper.github.io/schema/bean-mapping
>             https://dozermapper.github.io/schema/bean-mapping.xsd">
>     <mapping type="one-way" wildcard="false">
>       <class-a>org.acme.jaxb.BooksForm</class-a>
>       <class-b>org.acme.dto.Book</class-b>
>       <field>
>         <a>book[0].id</a>
>         <b>key</b>
>       </field>
>       <field>
>         <a>book[0].author</a>
>         <b>author</b>
>       </field>
>       <field>
>         <a>book[0].pubDate</a>
>         <b>publicationDate</b>
>       </field>
>       <field>
>         <a>book[0].price</a>
>         <b>price</b>
>       </field>
>     </mapping>
>   </mappings>
>
>
> I've tried to hard-code the mapping in a small part of the application
> and everything works fine even running the native executable. The same
> if I use Instant instead of Date. Unfortunately it's a complex
> microservice and I don't want to change the definition, said that
> Instant should be definitely meaningless for dates without seconds
>
> Am I missing something in Dozer (or Quarkus) configuration for
> java.util.Date fields? Or is it a bug related to native compilation
> for camel-quarkus-dozer?
>
> Many thanks
>