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());
}
