Calling a Java function with varargs parameter from XQuery
Friday, 30 June 2023 · 5 messages · last reply 3 Jul 2023
LV
Lizzi, Vincent30 Jun 2023 01:54 #
Hello BaseX people,
The Java language bindings in BaseX look like a very good way to use Java libraries from XQuery. I'm currently trying to use Lingua (https://github.com/pemistahl/lingua) with BaseX, and mostly have it working, but I've not been able to figure out how to call a Java function that takes a vararg (variable arguments) parameter.
Here is a bit of XQuery code that shows the problem. I'm using BaseX version 10.6 and the jar for Lingua version 1.2.2 has been added to the classpath. This query should return a LanguageDetectorBuilder object.
declare namespace Builder = "java:com.github.pemistahl.lingua.api.LanguageDetectorBuilder";
declare namespace Detector = "java:com.github.pemistahl.lingua.api.LanguageDetector";
declare namespace Language = "java:com.github.pemistahl.lingua.api.Language";let $builder :=
Builder:fromLanguages(
[
Language:ENGLISH(),
Language:DUTCH(),
Language:GERMAN(),
Language:SPANISH(),
Language:FRENCH()
]
)
return $builder
The above code produces this error message in the BaseX GUI:
[XPTY0004] com.github.pemistahl.lingua.api.LanguageDetectorBuilder:fromLanguages(com.github.pemistahl.lingua.api.Language[]) expected, (CArray) found.
If I try making the parameter a sequence instead of an array, replacing () parenthesis for the [] brackets, then this is the error message:
[XPTY0004] com.github.pemistahl.lingua.api.LanguageDetectorBuilder:fromLanguages(com.github.pemistahl.lingua.api.Language[]) expected, (List) found.
I've read through the Java Bindings page in the wiki and tried to rewrite the parameter in different ways, but so far have only gotten different error messages.
The signature for the fromLanguages function can be seen at https://github.com/pemistahl/lingua/blob/main/src/main/kotlin/com/github/pemistahl/lingua/api/LanguageDetectorBuilder.kt#L165
Is there a way to make this work?
Thanks,
Vincent
______________________________________________
Vincent M. Lizzi
Head of Information Standards | Taylor & Francis Group
530 Walnut St., Suite 850, Philadelphia, PA 19106
E-Mail: vincent.lizzi at taylorandfrancis.com<mailto:vincent.lizzi at taylorandfrancis.com> Web: www.tandfonline.com<http://www.tandfonline.com>
Taylor & Francis is a trading name of Informa UK Limited,
registered in England under no. 1072954
"Everything should be made as simple as possible, but not simpler."
Information Classification: General
LV
Lizzi, Vincent30 Jun 2023 16:18 #
Hello again,
I've also tried a variation with the parameter's type declared in the way described in the Java Bindings wiki page. Here is the code:
declare namespace Builder = "java:com.github.pemistahl.lingua.api.LanguageDetectorBuilder";
declare namespace Language = "java:com.github.pemistahl.lingua.api.Language";Builder:fromLanguages*com.github.pemistahl.lingua.api.Language...( (
Language:ENGLISH(),
Language:DUTCH(),
Language:GERMAN(),
Language:SPANISH(),
Language:FRENCH()
)
)
But this still produces an error message:
[XPTY0004] com.github.pemistahl.lingua.api.LanguageDetectorBuilder:fromLanguages(com.github.pemistahl.lingua.api.Language[]) expected, (List) found.
How should the parameter's list of values be written?
Thanks,
Vincent
_____________________________________________
Vincent M. Lizzi
Head of Information Standards | Taylor & Francis Group
vincent.lizzi at taylorandfrancis.com<mailto:vincent.lizzi at taylorandfrancis.com>
Information Classification: General
Quoted text · Lizzi, Vincent · 38 lines
From: Lizzi, Vincent Sent: Thursday, June 29, 2023 7:55 PM To: BaseX <basex-talk at mailman.uni-konstanz.de> Subject: Calling a Java function with varargs parameter from XQuery Hello BaseX people, The Java language bindings in BaseX look like a very good way to use Java libraries from XQuery. I'm currently trying to use Lingua (https://github.com/pemistahl/lingua) with BaseX, and mostly have it working, but I've not been able to figure out how to call a Java function that takes a vararg (variable arguments) parameter. Here is a bit of XQuery code that shows the problem. I'm using BaseX version 10.6 and the jar for Lingua version 1.2.2 has been added to the classpath. This query should return a LanguageDetectorBuilder object. declare namespace Builder = "java:com.github.pemistahl.lingua.api.LanguageDetectorBuilder"; declare namespace Detector = "java:com.github.pemistahl.lingua.api.LanguageDetector"; declare namespace Language = "java:com.github.pemistahl.lingua.api.Language"; let $builder := Builder:fromLanguages( [ Language:ENGLISH(), Language:DUTCH(), Language:GERMAN(), Language:SPANISH(), Language:FRENCH() ] ) return $builder The above code produces this error message in the BaseX GUI: [XPTY0004] com.github.pemistahl.lingua.api.LanguageDetectorBuilder:fromLanguages(com.github.pemistahl.lingua.api.Language[]) expected, (CArray) found. If I try making the parameter a sequence instead of an array, replacing () parenthesis for the [] brackets, then this is the error message: [XPTY0004] com.github.pemistahl.lingua.api.LanguageDetectorBuilder:fromLanguages(com.github.pemistahl.lingua.api.Language[]) expected, (List) found. I've read through the Java Bindings page in the wiki and tried to rewrite the parameter in different ways, but so far have only gotten different error messages. The signature for the fromLanguages function can be seen at https://github.com/pemistahl/lingua/blob/main/src/main/kotlin/com/github/pemistahl/lingua/api/LanguageDetectorBuilder.kt#L165 Is there a way to make this work? Thanks, Vincent Vincent M. Lizzi Head of Information Standards | Taylor & Francis Group 530 Walnut St., Suite 850, Philadelphia, PA 19106 E-Mail: vincent.lizzi at taylorandfrancis.com<mailto:vincent.lizzi at taylorandfrancis.com> Web: www.tandfonline.com<http://www.tandfonline.com> Taylor & Francis is a trading name of Informa UK Limited, registered in England under no. 1072954 "Everything should be made as simple as possible, but not simpler."
CG
Christian Grün1 Jul 2023 08:28 #
Hi Vincent,
In general, varargs parameters can be invoked similarly as functions with arrays, but it can be tricky to prepare the arguments in a way that they will be passed on as arrays. An explicit array conversion may help. This Java code…
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
System.out.println(String.join("/", list.toArray(String[]::new)));…can be written as:
declare namespace list = 'java.util.ArrayList';
let $list := list:new()
where list:add($list, 'a')
where list:add($list, 'b')
let $array := list:toArray($list)
(: with types: "join·CharSequence·CharSequence..." :)
return Q{java.lang.String}join('/', $array)When the code gets more complex, it’s still more convenient to write an additional Java wrapper class.
Hope this helps,
Christian
LV
Lizzi, Vincent3 Jul 2023 00:30 #
Hi Christian,
Thanks for the advice. I've tried a few variations based on your example. There seems to be a problem passing the Java array value to the Java function that has the varargs parameter.
I tried constructing the list in this manner, which produces the expected list.
declare namespace Language = "java:com.github.pemistahl.lingua.api.Language"; declare namespace List = 'java:java.util.List';
List:toArray(List:of(
Language:ENGLISH(),
Language:GERMAN()
)) ! (., string())
When I try passing the list to the Java constructor:
declare namespace Builder = "java:com.github.pemistahl.lingua.api.LanguageDetectorBuilder"; declare namespace Language = "java:com.github.pemistahl.lingua.api.Language"; declare namespace List = 'java:java.util.List';
Builder:fromLanguages·com.github.pemistahl.lingua.api.Language...( List:toArray(List:of(
Language:ENGLISH(),
Language:GERMAN()
)))
I get this error:
[XPTY0004] com.github.pemistahl.lingua.api.LanguageDetectorBuilder:fromLanguages(com.github.pemistahl.lingua.api.Language[]) expected, () found.
When I try constructing the list first and then passing the value using ArrayList:
declare namespace Builder = "java:com.github.pemistahl.lingua.api.LanguageDetectorBuilder";
declare namespace Language = "java:com.github.pemistahl.lingua.api.Language";
declare namespace list = 'java.util.ArrayList';
let $list := list:new() where list:add($list, Language:ENGLISH()) where list:add($list, Language:GERMAN())
let $array := list:toArray($list)
return Builder:fromLanguages·com.github.pemistahl.lingua.api.Language...($array)I get this error:
[XPTY0004] com.github.pemistahl.lingua.api.LanguageDetectorBuilder:fromLanguages(com.github.pemistahl.lingua.api.Language[]) expected, (VarRef) found.
I've tried other variations but each time get a slightly different error message, for such as:
[XPTY0004] com.github.pemistahl.lingua.api.LanguageDetectorBuilder:fromLanguages(com.github.pemistahl.lingua.api.Language[]) expected, (GFLWOR) found.
Do you have any suggestions?
Thank you,
Vincent
_____________________________________________
Vincent M. Lizzi
Head of Information Standards | Taylor & Francis Group
vincent.lizzi at taylorandfrancis.com
Information Classification: General
Quoted text · Christian Grün · 15 lines
-----Original Message----- From: Christian Grün <christian.gruen at gmail.com> Sent: Saturday, July 1, 2023 2:29 AM To: Lizzi, Vincent <Vincent.Lizzi at taylorandfrancis.com> Cc: BaseX <basex-talk at mailman.uni-konstanz.de> Subject: Re: [basex-talk] Calling a Java function with varargs parameter from XQuery Hi Vincent, In general, varargs parameters can be invoked similarly as functions with arrays, but it can be tricky to prepare the arguments in a way that they will be passed on as arrays. An explicit array conversion may help. This Java code… ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); System.out.println(String.join("/", list.toArray(String[]::new))); …can be written as: declare namespace list = 'java.util.ArrayList'; let $list := list:new() where list:add($list, 'a') where list:add($list, 'b') let $array := list:toArray($list) (: with types: "join·CharSequence·CharSequence..." :) return Q{java.lang.String}join('/', $array) When the code gets more complex, it’s still more convenient to write an additional Java wrapper class. Hope this helps, Christian
CG
Christian Grün3 Jul 2023 07:46 #
Hi Vincent,
Do you think you can provide me with a minimized self-contained Java example (possibly based on a native Java varargs function)?
Best,
Christian
Quoted text · Vincent · 82 lines
On Mon, Jul 3, 2023 at 12:30 AM Lizzi, Vincent <Vincent.Lizzi at taylorandfrancis.com> wrote: > > Hi Christian, > > Thanks for the advice. I've tried a few variations based on your example. There seems to be a problem passing the Java array value to the Java function that has the varargs parameter. > > I tried constructing the list in this manner, which produces the expected list. > > declare namespace Language = "java:com.github.pemistahl.lingua.api.Language"; > declare namespace List = 'java:java.util.List'; > List:toArray(List:of( > Language:ENGLISH(), > Language:GERMAN() > )) ! (., string()) > > When I try passing the list to the Java constructor: > > declare namespace Builder = "java:com.github.pemistahl.lingua.api.LanguageDetectorBuilder"; > declare namespace Language = "java:com.github.pemistahl.lingua.api.Language"; > declare namespace List = 'java:java.util.List'; > Builder:fromLanguages·com.github.pemistahl.lingua.api.Language...( > List:toArray(List:of( > Language:ENGLISH(), > Language:GERMAN() > ))) > > I get this error: > > [XPTY0004] com.github.pemistahl.lingua.api.LanguageDetectorBuilder:fromLanguages(com.github.pemistahl.lingua.api.Language[]) expected, () found. > > When I try constructing the list first and then passing the value using ArrayList: > > declare namespace Builder = "java:com.github.pemistahl.lingua.api.LanguageDetectorBuilder"; > declare namespace Language = "java:com.github.pemistahl.lingua.api.Language"; > declare namespace list = 'java.util.ArrayList'; > let $list := list:new() where list:add($list, Language:ENGLISH()) where list:add($list, Language:GERMAN()) > let $array := list:toArray($list) > return Builder:fromLanguages·com.github.pemistahl.lingua.api.Language...($array) > > I get this error: > > [XPTY0004] com.github.pemistahl.lingua.api.LanguageDetectorBuilder:fromLanguages(com.github.pemistahl.lingua.api.Language[]) expected, (VarRef) found. > > I've tried other variations but each time get a slightly different error message, for such as: > > [XPTY0004] com.github.pemistahl.lingua.api.LanguageDetectorBuilder:fromLanguages(com.github.pemistahl.lingua.api.Language[]) expected, (GFLWOR) found. > > Do you have any suggestions? > > Thank you, > Vincent > > _____________________________________________ > Vincent M. Lizzi > Head of Information Standards | Taylor & Francis Group > vincent.lizzi at taylorandfrancis.com > > > Information Classification: General > -----Original Message----- > From: Christian Grün <christian.gruen at gmail.com> > Sent: Saturday, July 1, 2023 2:29 AM > To: Lizzi, Vincent <Vincent.Lizzi at taylorandfrancis.com> > Cc: BaseX <basex-talk at mailman.uni-konstanz.de> > Subject: Re: [basex-talk] Calling a Java function with varargs parameter from XQuery > > Hi Vincent, > > In general, varargs parameters can be invoked similarly as functions with arrays, but it can be tricky to prepare the arguments in a way that they will be passed on as arrays. An explicit array conversion may help. This Java code… > > ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); System.out.println(String.join("/", list.toArray(String[]::new))); > > …can be written as: > > declare namespace list = 'java.util.ArrayList'; let $list := list:new() where list:add($list, 'a') where list:add($list, 'b') let $array := list:toArray($list) > (: with types: "join·CharSequence·CharSequence..." :) return Q{java.lang.String}join('/', $array) > > When the code gets more complex, it’s still more convenient to write an additional Java wrapper class. > > Hope this helps, > Christian
Written for BaseX 10.6. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery