Troubleshooting and FAQs
Troubleshooting Issues
Packaging Issue
Problem Description: After packaging Java API with Maven, it throws
NoClassDefFoundError: net/jpountz/lz4...
.
Cause: Maven packaging did not include third-party dependency jars.
Solution:
-
Include the dependency jars manually when running the jar file:
java -cp ".:./api-java-1.0.27-SNAPSHOT.jar:./lz4-java-1.7.1.jar" ...
-
Use the Maven assembly plugin to package dependencies.
Modify pom.xml:
<plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <appendAssemblyId>false</appendAssemblyId> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.xxdb.MTW_ParThread_Test.Main</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>assembly</goal> </goals> </execution> </executions> </plugin>
Package with Maven:
mvn assembly:assembly clean install
Wrong Package
no instance of type variable exist so that BasicIntVector conforms to Vector inference...
Cause: Incorrect Vector interface import.
Solution: Import the correct Vector
interface provided by
the API.
Escaping Errors
Script:
sqlFormat = "select * from pt where date(%s) = %s,SecurityID like '600%'";
conn.run(String.format(sqlFormat, arg));
Error:
java.util.UnknownFormatConversionException: Conversion = '''
Cause: In Java String.format
, %
is used
as a placeholder, which conflicts with SQL like
syntax.
Solution:
Escape %
using %%
:
sqlFormat = "select * from pt where date(%s) = %s, SecurityID like '600%%'";
Inconsistent Results with GUI
Problem Description:
Java API run
function results differ from GUI results.
API Script:
conn.login("admin", "123456", false); StringBuilder sb = new StringBuilder(); sb.append("'") .append("F:" + File.separator + "dolphinDB2" + File.separator + "DolphinDB_GUI_V1.30.13" + File.separator + "workspace" + File.separator + "test1" + File.separator + "scripts" + File.separator + "GenTradeTable.txt") .append("'"); Entity run = conn.run(sb.toString()); System.out.println("run.getString():" + run.getString());
DolphinDB GUI Script:
n=2000
syms=`YHOO`GE`MS`MSFT`JPM`ORCL`CISCO
timestamp=09:30:00+rand(18000, n)
sym=rand(syms, n)
qty=100*(1+rand(100,n))
price=5.0+rand(100.0, n)
t1=table(timestamp,sym,qty,price);
t1
Cause: Java API's run
method expects a script as a
string, differing from server run
method.
Solution:
Run the file's script in the API's run
method:
DBConnection conn = new DBConnection();
conn.connect("localhost",8848,"admin","123456");
StringBuilder sb = new StringBuilder();
String script = "run(\"D:/work/GenTradeTable.txt\")";
System.out.println(script);
BasicTable res = (BasicTable) conn.run(script);
System.out.println("run.getString():"+res.getString());
FAQs
Q: How to construct a Dictionary using Java API?
A: To construct a dictionary directly in DolphinDB using the Java API, you
can instantiate a BasicDictionary
by specifying the key and
value types (e.g., key is DT_INT
, value is
DT_STRING
). Then, you can use the put
method to insert key-value pairs. For example:
BasicDictionary dictionary = new BasicDictionary(Entity.DATA_TYPE.DT_INT, Entity.DATA_TYPE.DT_STRING); dictionary.put(new BasicInt(1),new BasicString("IBM")); System.out.println(dictionary.getString());
Q: How to get the column names and types of a table when only the table name is known?
A: If you only know the table name, you can use the
loadTable
function to get the table first and then use the
columnNames
function to retrieve the column names. For
example:
List<Entity> arguments1 = new ArrayList<Entity>(1); BasicTable table1 = (BasicTable) conn.run("loadTable('dfs://testDatabase','pt')"); arguments1.add(table1); BasicStringVector o1 = (BasicStringVector)conn.run("columnNames",arguments1); System.out.println(o1.getString());
Q: How to convert temporal values to integers when constructing
BasicDateVector
/ BasicTimeVector
in Java
API?
A: You can convert dates or times to integers using the following methods:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd"); DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HHmmssSSS"); Utils.countDays(LocalDate.parse(currentDate, dateFormatter)) Utils.countMilliseconds(LocalTime.parse(String.format("%09d", Integer.parseInt(localCurrentTime)), timeFormatter))
Q: How to get the number of successfully inserted records after calling
tableInsert
in Java API?
A: When you execute tableInsert
using the Java API, the
return value entity
is of type BasicInt
. You
can directly print entity
to see the number of successfully
inserted records. For example:
Entity entity = conn.run("tableInsert(...)");
System.out.println(((BasicInt) entity).getInt());
Q: Handling EOFException
after subscribing to a stream
table
Successfully reconnected and subscribed xxxx:8903/DemoStreamjavaStreamingApi java.io.EOFException at com.xxdb.io.AbstractExtendedDataInputStream.readUnsignedByte(AbstractExtendedDataInputStream.java:116) at com.xxdb.io.AbstractExtendedDataInputStream.readBoolean(AbstractExtendedDataInputStream.java:21) at com.xxdb.streaming.client.MessageParser.run(MessageParser.java:68) at java.lang.Thread.run(Thread.java:748)
A: The EOFException
may occur if multiple threads are
sharing a session, leading to buffer serialization failure.
Q: How to convert BasicTable
with array vector types to a
format accepted by MultiThreadedTableWriter::insert
?
A: Convert columns to BasicArrayVector
and then to
Entity[]
:
for (int rowIdx = 0; rowIdx < data.rows(); rowIdx++) { List<Object> row = new ArrayList<>(); for (int k = 0; k < data.columns(); k++) { Vector col = data.getColumn(k); if (col instanceof BasicArrayVector) { Vector vecVal = ((BasicArrayVector) col).getVectorValue(rowIdx); Entity[] vecValRes = new Entity[vecVal.rows()]; for (int vecValidx = 0; vecValidx < vecVal.rows(); vecValidx++) { vecValRes[vecValidx] = vecVal.get(vecValidx); } row.add(vecValRes); } else { row.add(col.get(rowIdx)); } } mtwWriter.insert(row.toArray()); }