[
http://issues.apache.org/jira/browse/DERBY-550?page=comments#action_12419724 ]
Andreas Korneliussen commented on DERBY-550:
--------------------------------------------
One more comment: there seems to be a client-side problem when streaming data
to the client.
I have created a table with a 64 MB blob in embedded mode, and if I try to get
the data with a scrollable resultset on the client side, it fails with
OutOfMemoryError in NetStatementReply.copyEXTDTA, which is caught in an
exception handler:
protected void copyEXTDTA(NetCursor netCursor) throws DisconnectException {
try {
parseLengthAndMatchCodePoint(CodePoint.EXTDTA);
byte[] data = null;
if (longValueForDecryption_ == null) {
data = (getData(null)).toByteArray();
} else {
data = longValueForDecryption_;
dssLength_ = 0;
longValueForDecryption_ = null;
}
netCursor.extdtaData_.add(data);
} catch (java.lang.OutOfMemoryError e) {
agent_.accumulateChainBreakingReadExceptionAndThrow(new
DisconnectException(agent_,
new ClientMessageId(SQLState.NET_LOB_DATA_TOO_LARGE_FOR_JVM),
e));
}
This again causes an assert in MessageUtil:
Exception in thread "main" org.apache.derby.shared.common.sanity.AssertFailure:
ASSERT FAILED Number of parameters expected for message id 58009.C.6 (0) does
not match number of arguments received (1)
at
org.apache.derby.shared.common.sanity.SanityManager.ASSERT(SanityManager.java:119)
at
org.apache.derby.shared.common.i18n.MessageUtil.formatMessage(MessageUtil.java:233)
at
org.apache.derby.shared.common.i18n.MessageUtil.getCompleteMessage(MessageUtil.java:142)
at
org.apache.derby.shared.common.i18n.MessageUtil.getCompleteMessage(MessageUtil.java:182)
at
org.apache.derby.shared.common.i18n.MessageUtil.getCompleteMessage(MessageUtil.java:98)
Using forward-only resultset:
Get this error:
java.sql.SQLException: Network protocol exception: DSS chained with same id at
end of same id chain parse. The connection has been terminated.
at
org.apache.derby.client.am.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:45)
at
org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:344)
at org.apache.derby.jdbc.ClientDriver.connect(ClientDriver.java:148)
at java.sql.DriverManager.getConnection(DriverManager.java:525)
at java.sql.DriverManager.getConnection(DriverManager.java:171)
at derbytest.BlobOutOfMem.main(BlobOutOfMem.java:59)
> BLOB : java.lang.OutOfMemoryError with network JDBC driver
> (org.apache.derby.jdbc.ClientDriver)
> -----------------------------------------------------------------------------------------------
>
> Key: DERBY-550
> URL: http://issues.apache.org/jira/browse/DERBY-550
> Project: Derby
> Type: Bug
> Components: JDBC, Network Server
> Versions: 10.1.1.0
> Environment: Any environment.
> Reporter: Grégoire Dubois
> Assignee: Tomohito Nakayama
>
> Using the org.apache.derby.jdbc.ClientDriver driver to access the
> Derby database through network, the driver is writting all the file into
> memory (RAM) before sending
> it to the database.
> Writting small files (smaller than 5Mo) into the database works fine,
> but it is impossible to write big files (40Mo for example, or more), without
> getting the
> exception java.lang.OutOfMemoryError.
> The org.apache.derby.jdbc.EmbeddedDriver doesn't have this problem.
> Here follows some code that creates a database, a table, and trys to write a
> BLOB. 2 parameters are to be changed for the code to work for you :
> DERBY_DBMS_PATH and FILE
> import NetNoLedge.Configuration.Configs;
> import org.apache.derby.drda.NetworkServerControl;
> import java.net.InetAddress;
> import java.io.*;
> import java.sql.*;
> /**
> *
> * @author greg
> */
> public class DerbyServer_JDBC_BLOB_test {
>
> // The unique instance of DerbyServer in the application.
> private static DerbyServer_JDBC_BLOB_test derbyServer;
>
> private NetworkServerControl server;
>
> private static final String DERBY_JDBC_DRIVER =
> "org.apache.derby.jdbc.ClientDriver";
> private static final String DERBY_DATABASE_NAME = "Test";
>
> // ###############################################################
> // ############### SET HERE THE EXISTING PATH YOU WANT ################
> // ###############################################################
> private static final String DERBY_DBMS_PATH = "/home/greg/DatabaseTest";
> // ###############################################################
> // ###############################################################
>
>
> private static int derbyPort = 9157;
> private static String userName = "user";
> private static String userPassword = "password";
>
> //
> ###################################################################################
> // ############# DEFINE HERE THE PATH TO THE FILE YOU WANT TO WRITE INTO
> THE DATABASE ###########
> // ############# TRY A 100kb-3Mb FILE, AND AFTER A 40Mb OR BIGGER FILE
> #########################
> //
> ###################################################################################
> private static final File FILE = new File("/home/greg/01.jpg");
> //
> ###################################################################################
> //
> ###################################################################################
>
> /**
> * <p>Used to test the server.
> */
> public static void main(String args[]) {
> try {
> DerbyServer_JDBC_BLOB_test.launchServer();
> DerbyServer_JDBC_BLOB_test server = getUniqueInstance();
> server.start();
> System.out.println("Server started");
>
> // After the server has been started, launch a first connection
> to the database to
> // 1) Create the database if it doesn't exist already,
> // 2) Create the tables if they don't exist already.
> Class.forName(DERBY_JDBC_DRIVER).newInstance();
> Connection connection = DriverManager.getConnection
> ("jdbc:derby://localhost:"+derbyPort+"/"+DERBY_DATABASE_NAME+";create=true",
> userName, userPassword);
> System.out.println("Network JDBC connection to Derby succeded.
> Database created if not created already.");
>
> Statement statement =
> connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
> ResultSet.CONCUR_READ_ONLY);
> Statement statement2;
> // Create the table "file" if it doesn't already exist.
> String [] tableNames={"file"};
> boolean exist;
> String currentTable;
> ResultSet result = statement.executeQuery("SELECT TABLENAME FROM
> SYS.SYSTABLES");
> for (int i=0;i<tableNames.length;i++) {
> exist=false;
> while (result.next()){
> if (tableNames[i].equalsIgnoreCase(result.getString(1)))
> exist=true;
> }
>
> if (!exist) {
> statement2 = connection.createStatement();
> statement2.execute("CREATE TABLE file (" +
> "file BLOB(2G) NOT NULL)");
> connection.commit();
> }
> result.beforeFirst();
> }
> System.out.println("Table file created if not created already");
>
> System.out.println("File insertion into BLOB");
> FileInputStream inputStream = new FileInputStream(FILE);
> PreparedStatement preparedStatement =
> connection.prepareStatement("INSERT INTO file(file) VALUES (?)");
> preparedStatement.setBinaryStream(1,inputStream,(int)
> FILE.length());
> preparedStatement .execute();
> connection.commit();
> System.out.println("File inserted into BLOB");
> }
> catch (Exception e) {
> e.printStackTrace();
> }
> }
>
> /** Creates a new instance of MckoiServer
> * Password is used at the database creation. It will be the database
> password once created.
> */
> private DerbyServer_JDBC_BLOB_test() throws Exception {
> System.setProperty("derby.system.home", DERBY_DBMS_PATH);
>
> // Set the server to request an authentification.
> System.setProperty("derby.authentication.provider", "BUILTIN");
> System.setProperty("derby.connection.requireAuthentication", "true");
>
> // Create a user that can connect to Derby.
> System.setProperty("derby.user."+userName, userPassword);
>
> // Set Derby to grant full access to the created user (to all the
> databases).
> System.setProperty("derby.database.fullAccessUsers", userName);
>
> //System.setProperty("derby.system.bootAll", "true");
>
> // See if the 9157 port is already taken.
> // Change it if necessary.
> boolean isPortFree = false;
> while ( !isPortFree ) {
> try {
> java.net.ServerSocket serverTest = new
> java.net.ServerSocket(derbyPort);
> serverTest.close();
> serverTest = null;
>
> isPortFree = true;
> }
> catch (Exception e) {
> System.out.println("Port already in use : "+derbyPort);
> derbyPort++;
> System.out.println("Try with port "+derbyPort);
> }
> }
>
> server = new
> NetworkServerControl(InetAddress.getByName("localhost"),derbyPort);
> }
>
> public static void launchServer() throws Exception {
> derbyServer = new DerbyServer_JDBC_BLOB_test();
> }
>
> public static DerbyServer_JDBC_BLOB_test getUniqueInstance() {
> return derbyServer;
> }
>
> /**
> * <p>Start the server.
> */
> public void start() {
> try {
> server.start(null);
> }
> catch (Exception e) {
> e.printStackTrace(System.err);
> }
> }
>
> /**
> * <p>Stop the server.
> */
> public void stop() {
> try {
> server.shutdown();
> }
> catch (Exception e) {
> e.printStackTrace(System.err);
> }
> }
> }
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira