Jump to navigation Jump to search
154 bytes added ,  13:00, 27 February 2020
no edit summary
In the following example, Java’s {{Code|Math}} class is referenced. When executed, the query returns the cosine of an angle by calling the static method {{Code|cos()}}, and the value of π by addressing the static variable via {{Code|PI()}}:
<pre classsyntaxhighlight lang="brush:xquery">
declare namespace math = "java:java.lang.Math";
math:cos(xs:double(0)), math:PI()
With the [[XQuery 3.0#Expanded QNames|Expanded QName]] notation of XQuery 3.0,
the namespace can directly be embedded in the function call:
<pre classsyntaxhighlight lang="brush:xquery">
The constructor of a class can be invoked by calling the virtual function {{Code|new()}}. Instance methods can then called by passing on the resulting Java object as first argument. In the following example, 256 bytes are written to the file {{Code|output.txt}}. First, a new {{Code|FileWriter}} instance is created, and its {{Code|write()}} function is called in the next step:
<pre classsyntaxhighlight lang="brush:xquery">declare namespace fw = "";
let $file := fw:new('output.txt')
return (
If the result of a Java call contains invalid XML characters, it will be rejected. The validity check can be disabled by setting {{Option|CHECKSTRINGS}} to false. In the example below, a file with a single {{Code|00}} byte is written, and this file will then be accessed by via Java functions:
<pre classsyntaxhighlight lang="brush:xquery">
declare namespace br = '';
declare namespace fr = '';
file:write-binary('00.bin', xs:hexBinary('00')),
br:new(fr:new('00.bin')) ! (br:readLine(.), br:close(.))
Note that Java code cannot be pre-compiled, and will as such be evaluated slower than optimized XQuery code.
In the (side-effecting) example below, the size of a Java hash set is returned. The boolean values that are returned by {{Code|set:add()}} are swallowed:
<pre classsyntaxhighlight lang="brush:xquery">
import module namespace set = "java:java.util.HashSet";
The execution of imported classes is more efficient than the execution of instances that are created at runtime via {{Code|new()}}. A drawback is that no arguments can be passed on to the class constructor. As a consequence, the import fails if the addressed class has no default constructor, but at least one constructor with arguments.
In the following code, information from the static query context is returned by the first function, and a query exception is raised by the second function:
<pre classsyntaxhighlight lang="brush:xquery">
import module namespace context = 'org.basex.examples.query.ContextModule';
element error { $err:description }
The imported Java class is shown below:
<pre classsyntaxhighlight lang="brush:java">
package org.basex.examples.query;
The result will look as follows:
<pre classsyntaxhighlight lang="brush:xml">
<error>Integer conversion failed: abc</error>
Please visit the XQuery 3.0 specification if you want to get more insight into
By default, a Java function will be executed in parallel with other code. However, if a Java function performs sensitive write operations, it is advisable to explicitly lock the code. This can be realized via locking annotations:
<pre classsyntaxhighlight lang="brush:java">
@Lock(write = { "HEAVYIO" })
public void write() {
// ...
If an XQuery expression is run which calls the Java {{Code|write()}} function, every other query that calls {{Code|write()}} or {{Code|read()}} needs to wait for the query to be finished. If a query calls the {{Code|read()}} function, only those queries are queued that call {{Code|write()}}, because this function is only annotated with a {{Code|read}} lock. More details on parallel query execution can be found in the article on [[Transaction Management]].
Bureaucrats, editor, reviewer, Administrators


Navigation menu