Java type mismatch when reflecting.

Thursday, 15 April 2021 · 2 messages
AM
Andreas Mixich15 Apr 2021 04:19 #
Hi I can successfully create an object instance of https://www.stringtemplate.org/api/index.html when using the parameter-less default init:
    declare namespace ST = 'java:org.stringtemplate.v4.ST';
    let $template := "Hello <who>"
    let $stInstance := ST:new($template)
    let $call := ST:add($stInstance, "who", "World!")
    return ST:render($stInstance)
Template delimiters can be changed by supplying left and right delimiters (type char) upon init (by default ST4 uses < and > as template delimiters). The signature for this would be: ST(java.lang.String template, char delimiterStartChar, char delimiterStopChar) Documentation is at https://www.stringtemplate.org/api/org/stringtemplate/v4/ST.html#ST-java.lang.String-char-char- So I defined the types at invocation, but executing following code I get an error.
    declare namespace ST = 'java:org.stringtemplate.v4.ST';
    let $template := "Hello $who$"
    let $stInstance := ST:new·java.lang.String·char·char($template,"$","$")
    let $call := ST:add($stInstance, "who", "World!")
    return ST:render($stInstance)
The error is: [XPTY0004] java.lang.IllegalArgumentException: argument type mismatch. Caused by: org.stringtemplate.v4.ST(String, String, String). The query plan of this unsuccessfull invocation is:
    <QueryPlan compiled="true" updating="false">
      <GFLWOR type="item()*">
        <Let type="item()*" name="$stInstance" id="1">
          <DynJavaConstr name="org.stringtemplate.v4.ST" type="item()*">
            <Str type="xs:string" size="1">Hello $who$</Str>
            <Str type="xs:string" size="1">$</Str>
            <Str type="xs:string" size="1">$</Str>
          </DynJavaConstr>
        </Let>
        <List type="item()*">
          <ProfVoid name="prof:void" type="empty-sequence()" size="0">
            <DynJavaFunc name="org.stringtemplate.v4.ST:add" type="item()*">
              <VarRef type="item()*" name="$stInstance" id="1"/>
              <Str type="xs:string" size="1">who</Str>
              <Str type="xs:string" size="1">World!</Str>
            </DynJavaFunc>
          </ProfVoid>
          <DynJavaFunc name="org.stringtemplate.v4.ST:render"
type="item()*">
            <VarRef type="item()*" name="$stInstance" id="1"/>
          </DynJavaFunc>
        </List>
      </GFLWOR>
    </QueryPlan>
I can see no deviation from https://docs.basex.org/wiki/Java_Bindings#Functions_and_Variables in my code. What am I doing wrong? Thanks.
-- Goody Bye, Minden jót, Mit freundlichen Grüßen, Andreas Mixich
CG
Christian Grün15 Apr 2021 18:25 #
Hi Andreas, Unfortunately, it’s a pretty sophisticated challenge to define a comprehensive and unambiguous mapping for Java and XQuery types. As there is no ideal counterpart in XQuery for char (xs:unsignedShort may be closest, but it’s normally used to represent numbers, not characters), both char and String is currently mapped to xs:string, and xs:string is converted back to a String instance. In your example, it looks as if xs:string could also be converted to a char value, but as a constructor or Java function might also expect a generic Object as argument, there is no chance to define a static mapping for such types. In some cases, such as for char, we might be successful to detect better mappings at runtime – but as a general guideline, I tend to recommend users to write some additional Java/XQuery wrapper code and use it as entry point for XQuery function calls. If required, the result can also be packaged and (un)installed in the BaseX repository, as shown in [1]. Hope this helps, Christian [1] https://docs.basex.org/wiki/Repository#Combined
Quoted text · Andreas Mixich · 73 lines
On Thu, Apr 15, 2021 at 4:19 AM Andreas Mixich <mixich.andreas at gmail.com> wrote: > > Hi > > I can successfully create an object instance of > https://www.stringtemplate.org/api/index.html > when using the parameter-less default init: > > declare namespace ST = 'java:org.stringtemplate.v4.ST'; > let $template := "Hello &lt;who&gt;" > let $stInstance := ST:new($template) > let $call := ST:add($stInstance, "who", "World!") > return ST:render($stInstance) > > Template delimiters can be changed by supplying left and right > delimiters (type char) upon init > (by default ST4 uses < and > as template delimiters). The signature for > this would be: > > ST(java.lang.String template, char delimiterStartChar, char > delimiterStopChar) > > Documentation is at > https://www.stringtemplate.org/api/org/stringtemplate/v4/ST.html#ST-java.lang.String-char-char- > > So I defined the types at invocation, but executing following code I get > an error. > > declare namespace ST = 'java:org.stringtemplate.v4.ST'; > let $template := "Hello $who$" > let $stInstance := ST:new·java.lang.String·char·char($template,"$","$") > let $call := ST:add($stInstance, "who", "World!") > return ST:render($stInstance) > > The error is: > > [XPTY0004] java.lang.IllegalArgumentException: argument type mismatch. > Caused by: org.stringtemplate.v4.ST(String, String, String). > > The query plan of this unsuccessfull invocation is: > > <QueryPlan compiled="true" updating="false"> > <GFLWOR type="item()*"> > <Let type="item()*" name="$stInstance" id="1"> > <DynJavaConstr name="org.stringtemplate.v4.ST" type="item()*"> > <Str type="xs:string" size="1">Hello $who$</Str> > <Str type="xs:string" size="1">$</Str> > <Str type="xs:string" size="1">$</Str> > </DynJavaConstr> > </Let> > <List type="item()*"> > <ProfVoid name="prof:void" type="empty-sequence()" size="0"> > <DynJavaFunc name="org.stringtemplate.v4.ST:add" type="item()*"> > <VarRef type="item()*" name="$stInstance" id="1"/> > <Str type="xs:string" size="1">who</Str> > <Str type="xs:string" size="1">World!</Str> > </DynJavaFunc> > </ProfVoid> > <DynJavaFunc name="org.stringtemplate.v4.ST:render" > type="item()*"> > <VarRef type="item()*" name="$stInstance" id="1"/> > </DynJavaFunc> > </List> > </GFLWOR> > </QueryPlan> > > I can see no deviation from > https://docs.basex.org/wiki/Java_Bindings#Functions_and_Variables > in my code. What am I doing wrong? Thanks. > > -- > Goody Bye, Minden jót, Mit freundlichen Grüßen, > Andreas Mixich

⚡Generated with XQuery