提交 43919469 authored 作者: Thomas Mueller's avatar Thomas Mueller

MVStore: reduced dependencies to other H2 classes.

上级 581f5126
...@@ -18,7 +18,10 @@ Change Log ...@@ -18,7 +18,10 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>There was a way to prevent a database from being re-opened, <ul><li>Issue 565: MVStore: concurrently adding LOB objects
(with MULTI_THREADED option) resulted in a NullPointerException.
</li><li>MVStore: reduced dependencies to other H2 classes.
</li><li>There was a way to prevent a database from being re-opened,
by creating a column constraint that references a table with a higher id. by creating a column constraint that references a table with a higher id.
This is now detected, and creating the table is prohibited. This is now detected, and creating the table is prohibited.
In future versions of H2, most likely creating references to other In future versions of H2, most likely creating references to other
......
...@@ -752,7 +752,7 @@ To build just the MVStore (without the database engine), run: ...@@ -752,7 +752,7 @@ To build just the MVStore (without the database engine), run:
./build.sh jarMVStore ./build.sh jarMVStore
</pre> </pre>
<p> <p>
This will create the file <code>bin/h2mvstore-${version}.jar</code> (about 130 KB). This will create the file <code>bin/h2mvstore-${version}.jar</code> (about 200 KB).
</p> </p>
<!-- [close] { --></div></td></tr></table><!-- } --><!-- analytics --></body></html> <!-- [close] { --></div></td></tr></table><!-- } --><!-- analytics --></body></html>
...@@ -3,6 +3,7 @@ svn up ...@@ -3,6 +3,7 @@ svn up
./build.sh spellcheck ./build.sh spellcheck
./build.sh javadocImpl ./build.sh javadocImpl
./build.sh docs ./build.sh docs
./build.sh jarMVStore (should be about 200 KB)
Update Constants.java - change version and build number Update Constants.java - change version and build number
Update changelog.html - add new version, remove oldest Update changelog.html - add new version, remove oldest
Update newsfeed.sql - add new version, remove oldest Update newsfeed.sql - add new version, remove oldest
......
...@@ -14,7 +14,6 @@ import java.util.Properties; ...@@ -14,7 +14,6 @@ import java.util.Properties;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.jdbc.JdbcConnection; import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.TraceSystem;
import org.h2.upgrade.DbUpgrade; import org.h2.upgrade.DbUpgrade;
/*## Java 1.7 ## /*## Java 1.7 ##
...@@ -161,7 +160,7 @@ public class Driver implements java.sql.Driver { ...@@ -161,7 +160,7 @@ public class Driver implements java.sql.Driver {
DriverManager.registerDriver(INSTANCE); DriverManager.registerDriver(INSTANCE);
} }
} catch (SQLException e) { } catch (SQLException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
return INSTANCE; return INSTANCE;
} }
...@@ -176,7 +175,7 @@ public class Driver implements java.sql.Driver { ...@@ -176,7 +175,7 @@ public class Driver implements java.sql.Driver {
DriverManager.deregisterDriver(INSTANCE); DriverManager.deregisterDriver(INSTANCE);
} }
} catch (SQLException e) { } catch (SQLException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
} }
......
...@@ -56,6 +56,7 @@ import org.h2.table.TableView; ...@@ -56,6 +56,7 @@ import org.h2.table.TableView;
import org.h2.tools.DeleteDbFiles; import org.h2.tools.DeleteDbFiles;
import org.h2.tools.Server; import org.h2.tools.Server;
import org.h2.util.BitField; import org.h2.util.BitField;
import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.NetUtils; import org.h2.util.NetUtils;
import org.h2.util.New; import org.h2.util.New;
...@@ -486,7 +487,7 @@ public class Database implements DataHandler { ...@@ -486,7 +487,7 @@ public class Database implements DataHandler {
traceSystem.close(); traceSystem.close();
} }
} catch (DbException e) { } catch (DbException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
} }
Engine.getInstance().close(databaseName); Engine.getInstance().close(databaseName);
...@@ -1996,7 +1997,7 @@ public class Database implements DataHandler { ...@@ -1996,7 +1997,7 @@ public class Database implements DataHandler {
} else { } else {
try { try {
eventListener = (DatabaseEventListener) eventListener = (DatabaseEventListener)
Utils.loadUserClass(className).newInstance(); JdbcUtils.loadUserClass(className).newInstance();
String url = databaseURL; String url = databaseURL;
if (cipher != null) { if (cipher != null) {
url += ";CIPHER=" + cipher; url += ";CIPHER=" + cipher;
...@@ -2726,7 +2727,7 @@ public class Database implements DataHandler { ...@@ -2726,7 +2727,7 @@ public class Database implements DataHandler {
!serializerName.equals("null")) { !serializerName.equals("null")) {
try { try {
javaObjectSerializer = (JavaObjectSerializer) javaObjectSerializer = (JavaObjectSerializer)
Utils.loadUserClass(serializerName).newInstance(); JdbcUtils.loadUserClass(serializerName).newInstance();
} catch (Exception e) { } catch (Exception e) {
throw DbException.convert(e); throw DbException.convert(e);
} }
......
...@@ -13,6 +13,7 @@ import java.lang.reflect.Modifier; ...@@ -13,6 +13,7 @@ import java.lang.reflect.Modifier;
import java.sql.Connection; import java.sql.Connection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import org.h2.Driver; import org.h2.Driver;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Parser; import org.h2.command.Parser;
...@@ -22,11 +23,11 @@ import org.h2.message.Trace; ...@@ -22,11 +23,11 @@ import org.h2.message.Trace;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.schema.SchemaObjectBase; import org.h2.schema.SchemaObjectBase;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.util.JdbcUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.SourceCompiler; import org.h2.util.SourceCompiler;
import org.h2.util.StatementBuilder; import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.util.Utils;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueArray; import org.h2.value.ValueArray;
...@@ -143,7 +144,7 @@ public class FunctionAlias extends SchemaObjectBase { ...@@ -143,7 +144,7 @@ public class FunctionAlias extends SchemaObjectBase {
} }
private void loadClass() { private void loadClass() {
Class<?> javaClass = Utils.loadUserClass(className); Class<?> javaClass = JdbcUtils.loadUserClass(className);
Method[] methods = javaClass.getMethods(); Method[] methods = javaClass.getMethods();
ArrayList<JavaMethod> list = New.arrayList(); ArrayList<JavaMethod> list = New.arrayList();
for (int i = 0, len = methods.length; i < len; i++) { for (int i = 0, len = methods.length; i < len; i++) {
......
...@@ -9,6 +9,7 @@ package org.h2.engine; ...@@ -9,6 +9,7 @@ package org.h2.engine;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayList; import java.util.ArrayList;
import org.h2.api.DatabaseEventListener; import org.h2.api.DatabaseEventListener;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.JavaObjectSerializer; import org.h2.api.JavaObjectSerializer;
...@@ -25,13 +26,13 @@ import org.h2.store.FileStore; ...@@ -25,13 +26,13 @@ import org.h2.store.FileStore;
import org.h2.store.LobStorageFrontend; import org.h2.store.LobStorageFrontend;
import org.h2.store.LobStorageInterface; import org.h2.store.LobStorageInterface;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.NetUtils; import org.h2.util.NetUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.SmallLRUCache; import org.h2.util.SmallLRUCache;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.util.TempFileDeleter; import org.h2.util.TempFileDeleter;
import org.h2.util.Utils;
import org.h2.value.Transfer; import org.h2.value.Transfer;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -410,7 +411,7 @@ public class SessionRemote extends SessionWithState implements DataHandler { ...@@ -410,7 +411,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
if (className != null) { if (className != null) {
className = StringUtils.trim(className, true, true, "'"); className = StringUtils.trim(className, true, true, "'");
try { try {
eventListener = (DatabaseEventListener) Utils eventListener = (DatabaseEventListener) JdbcUtils
.loadUserClass(className).newInstance(); .loadUserClass(className).newInstance();
} catch (Throwable e) { } catch (Throwable e) {
throw DbException.convert(e); throw DbException.convert(e);
...@@ -796,7 +797,7 @@ public class SessionRemote extends SessionWithState implements DataHandler { ...@@ -796,7 +797,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
serializerFQN = serializerFQN.trim(); serializerFQN = serializerFQN.trim();
if (!serializerFQN.isEmpty() && !serializerFQN.equals("null")) { if (!serializerFQN.isEmpty() && !serializerFQN.equals("null")) {
try { try {
javaObjectSerializer = (JavaObjectSerializer) Utils javaObjectSerializer = (JavaObjectSerializer) JdbcUtils
.loadUserClass(serializerFQN).newInstance(); .loadUserClass(serializerFQN).newInstance();
} catch (Exception e) { } catch (Exception e) {
throw DbException.convert(e); throw DbException.convert(e);
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
*/ */
package org.h2.engine; package org.h2.engine;
import org.h2.message.TraceSystem;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.Utils; import org.h2.util.Utils;
...@@ -172,7 +171,7 @@ public class SysProperties { ...@@ -172,7 +171,7 @@ public class SysProperties {
* error. * error.
*/ */
public static final int DATASOURCE_TRACE_LEVEL = public static final int DATASOURCE_TRACE_LEVEL =
Utils.getProperty("h2.dataSourceTraceLevel", TraceSystem.ERROR); Utils.getProperty("h2.dataSourceTraceLevel", 1);
/** /**
* System property <code>h2.delayWrongPasswordMin</code> * System property <code>h2.delayWrongPasswordMin</code>
......
...@@ -6,18 +6,18 @@ ...@@ -6,18 +6,18 @@
*/ */
package org.h2.engine; package org.h2.engine;
import org.h2.api.AggregateFunction; import java.sql.Connection;
import java.sql.SQLException;
import org.h2.api.Aggregate; import org.h2.api.Aggregate;
import org.h2.api.AggregateFunction;
import org.h2.command.Parser; import org.h2.command.Parser;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.util.Utils; import org.h2.util.JdbcUtils;
import org.h2.value.DataType; import org.h2.value.DataType;
import java.sql.Connection;
import java.sql.SQLException;
/** /**
* Represents a user-defined aggregate function. * Represents a user-defined aggregate function.
*/ */
...@@ -37,7 +37,7 @@ public class UserAggregate extends DbObjectBase { ...@@ -37,7 +37,7 @@ public class UserAggregate extends DbObjectBase {
public Aggregate getInstance() { public Aggregate getInstance() {
if (javaClass == null) { if (javaClass == null) {
javaClass = Utils.loadUserClass(className); javaClass = JdbcUtils.loadUserClass(className);
} }
Object obj; Object obj;
try { try {
......
...@@ -40,6 +40,7 @@ import org.h2.message.DbException; ...@@ -40,6 +40,7 @@ import org.h2.message.DbException;
import org.h2.message.TraceObject; import org.h2.message.TraceObject;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.util.CloseWatcher; import org.h2.util.CloseWatcher;
import org.h2.util.JdbcUtils;
import org.h2.util.Utils; import org.h2.util.Utils;
import org.h2.value.CompareMode; import org.h2.value.CompareMode;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -1908,7 +1909,7 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -1908,7 +1909,7 @@ public class JdbcConnection extends TraceObject implements Connection {
} }
case Value.JAVA_OBJECT: case Value.JAVA_OBJECT:
if (SysProperties.serializeJavaObject) { if (SysProperties.serializeJavaObject) {
o = Utils.deserialize(v.getBytesNoCopy(), session.getDataHandler()); o = JdbcUtils.deserialize(v.getBytesNoCopy(), session.getDataHandler());
break; break;
} }
default: default:
......
...@@ -8,7 +8,9 @@ package org.h2.message; ...@@ -8,7 +8,9 @@ package org.h2.message;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.Locale; import java.util.Locale;
...@@ -63,9 +65,9 @@ public class DbException extends RuntimeException { ...@@ -63,9 +65,9 @@ public class DbException extends RuntimeException {
} }
} }
} catch (OutOfMemoryError e) { } catch (OutOfMemoryError e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} catch (IOException e) { } catch (IOException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
} }
...@@ -239,7 +241,7 @@ public class DbException extends RuntimeException { ...@@ -239,7 +241,7 @@ public class DbException extends RuntimeException {
*/ */
public static RuntimeException throwInternalError(String s) { public static RuntimeException throwInternalError(String s) {
RuntimeException e = new RuntimeException(s); RuntimeException e = new RuntimeException(s);
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
throw e; throw e;
} }
...@@ -371,4 +373,16 @@ public class DbException extends RuntimeException { ...@@ -371,4 +373,16 @@ public class DbException extends RuntimeException {
this.source = source; this.source = source;
} }
/**
* Write the exception to the driver manager log writer if configured.
*
* @param e the exception
*/
public static void traceThrowable(Throwable e) {
PrintWriter writer = DriverManager.getLogWriter();
if (writer != null) {
e.printStackTrace(writer);
}
}
} }
...@@ -371,7 +371,7 @@ public class TraceObject { ...@@ -371,7 +371,7 @@ public class TraceObject {
protected SQLException logAndConvert(Exception ex) { protected SQLException logAndConvert(Exception ex) {
SQLException e = DbException.toSQLException(ex); SQLException e = DbException.toSQLException(ex);
if (trace == null) { if (trace == null) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} else { } else {
int errorCode = e.getErrorCode(); int errorCode = e.getErrorCode();
if (errorCode >= 23000 && errorCode < 24000) { if (errorCode >= 23000 && errorCode < 24000) {
......
...@@ -10,9 +10,7 @@ import java.io.IOException; ...@@ -10,9 +10,7 @@ import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.Writer; import java.io.Writer;
import java.sql.DriverManager;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
...@@ -119,18 +117,6 @@ public class TraceSystem implements TraceWriter { ...@@ -119,18 +117,6 @@ public class TraceSystem implements TraceWriter {
this.sysOut = out; this.sysOut = out;
} }
/**
* Write the exception to the driver manager log writer if configured.
*
* @param e the exception
*/
public static void traceThrowable(Throwable e) {
PrintWriter writer = DriverManager.getLogWriter();
if (writer != null) {
e.printStackTrace(writer);
}
}
/** /**
* Get or create a trace object for this module. Trace modules with names * Get or create a trace object for this module. Trace modules with names
* such as "JDBC[1]" are not cached (modules where the name ends with "]"). * such as "JDBC[1]" are not cached (modules where the name ends with "]").
......
...@@ -28,8 +28,8 @@ import org.h2.mvstore.db.MVTableEngine; ...@@ -28,8 +28,8 @@ import org.h2.mvstore.db.MVTableEngine;
import org.h2.table.RegularTable; import org.h2.table.RegularTable;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.table.TableLink; import org.h2.table.TableLink;
import org.h2.util.JdbcUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.Utils;
/** /**
* A schema as created by the SQL statement * A schema as created by the SQL statement
...@@ -576,7 +576,7 @@ public class Schema extends DbObjectBase { ...@@ -576,7 +576,7 @@ public class Schema extends DbObjectBase {
if (data.tableEngine != null) { if (data.tableEngine != null) {
TableEngine engine; TableEngine engine;
try { try {
engine = (TableEngine) Utils.loadUserClass(data.tableEngine).newInstance(); engine = (TableEngine) JdbcUtils.loadUserClass(data.tableEngine).newInstance();
} catch (Exception e) { } catch (Exception e) {
throw DbException.convert(e); throw DbException.convert(e);
} }
......
...@@ -18,7 +18,7 @@ import org.h2.message.DbException; ...@@ -18,7 +18,7 @@ import org.h2.message.DbException;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.util.Utils; import org.h2.util.JdbcUtils;
import org.h2.util.StatementBuilder; import org.h2.util.StatementBuilder;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -67,7 +67,7 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -67,7 +67,7 @@ public class TriggerObject extends SchemaObjectBase {
try { try {
Session sysSession = database.getSystemSession(); Session sysSession = database.getSystemSession();
Connection c2 = sysSession.createConnection(false); Connection c2 = sysSession.createConnection(false);
Object obj = Utils.loadUserClass(triggerClassName).newInstance(); Object obj = JdbcUtils.loadUserClass(triggerClassName).newInstance();
triggerCallback = (Trigger) obj; triggerCallback = (Trigger) obj;
triggerCallback.init(c2, getSchema().getName(), getName(), triggerCallback.init(c2, getSchema().getName(), getName(),
table.getName(), before, typeMask); table.getName(), before, typeMask);
......
...@@ -25,7 +25,6 @@ import org.h2.Driver; ...@@ -25,7 +25,6 @@ import org.h2.Driver;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.TraceSystem;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
import org.h2.util.NetUtils; import org.h2.util.NetUtils;
import org.h2.util.New; import org.h2.util.New;
...@@ -139,7 +138,7 @@ public class TcpServer implements Service { ...@@ -139,7 +138,7 @@ public class TcpServer implements Service {
managementDbAdd.setString(3, user); managementDbAdd.setString(3, user);
managementDbAdd.execute(); managementDbAdd.execute();
} catch (SQLException e) { } catch (SQLException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
} }
...@@ -153,7 +152,7 @@ public class TcpServer implements Service { ...@@ -153,7 +152,7 @@ public class TcpServer implements Service {
managementDbRemove.setInt(1, id); managementDbRemove.setInt(1, id);
managementDbRemove.execute(); managementDbRemove.execute();
} catch (SQLException e) { } catch (SQLException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
} }
...@@ -162,7 +161,7 @@ public class TcpServer implements Service { ...@@ -162,7 +161,7 @@ public class TcpServer implements Service {
try { try {
managementDb.close(); managementDb.close();
} catch (SQLException e) { } catch (SQLException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
managementDb = null; managementDb = null;
} }
...@@ -260,7 +259,7 @@ public class TcpServer implements Service { ...@@ -260,7 +259,7 @@ public class TcpServer implements Service {
serverSocket = NetUtils.closeSilently(serverSocket); serverSocket = NetUtils.closeSilently(serverSocket);
} catch (Exception e) { } catch (Exception e) {
if (!stop) { if (!stop) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
} }
stopManagementDb(); stopManagementDb();
...@@ -296,7 +295,7 @@ public class TcpServer implements Service { ...@@ -296,7 +295,7 @@ public class TcpServer implements Service {
try { try {
serverSocket.close(); serverSocket.close();
} catch (IOException e) { } catch (IOException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} catch (NullPointerException e) { } catch (NullPointerException e) {
// ignore // ignore
} }
...@@ -306,7 +305,7 @@ public class TcpServer implements Service { ...@@ -306,7 +305,7 @@ public class TcpServer implements Service {
try { try {
listenerThread.join(1000); listenerThread.join(1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
} }
} }
...@@ -317,7 +316,7 @@ public class TcpServer implements Service { ...@@ -317,7 +316,7 @@ public class TcpServer implements Service {
try { try {
c.getThread().join(100); c.getThread().join(100);
} catch (Exception e) { } catch (Exception e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
} }
} }
......
...@@ -18,7 +18,6 @@ import java.sql.SQLException; ...@@ -18,7 +18,6 @@ import java.sql.SQLException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
...@@ -30,7 +29,7 @@ import java.util.TimeZone; ...@@ -30,7 +29,7 @@ import java.util.TimeZone;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
import org.h2.message.TraceSystem; import org.h2.message.DbException;
import org.h2.server.Service; import org.h2.server.Service;
import org.h2.server.ShutdownHandler; import org.h2.server.ShutdownHandler;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
...@@ -406,7 +405,7 @@ public class WebServer implements Service { ...@@ -406,7 +405,7 @@ public class WebServer implements Service {
try { try {
listenerThread.join(1000); listenerThread.join(1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
} }
// TODO server: using a boolean 'now' argument? a timeout? // TODO server: using a boolean 'now' argument? a timeout?
...@@ -477,7 +476,7 @@ public class WebServer implements Service { ...@@ -477,7 +476,7 @@ public class WebServer implements Service {
} }
} }
} catch (IOException e) { } catch (IOException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
session.put("text", new HashMap<Object, Object>(text)); session.put("text", new HashMap<Object, Object>(text));
} }
...@@ -563,7 +562,7 @@ public class WebServer implements Service { ...@@ -563,7 +562,7 @@ public class WebServer implements Service {
return SortedProperties.loadProperties( return SortedProperties.loadProperties(
serverPropertiesDir + "/" + Constants.SERVER_PROPERTIES_NAME); serverPropertiesDir + "/" + Constants.SERVER_PROPERTIES_NAME);
} catch (Exception e) { } catch (Exception e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
return new Properties(); return new Properties();
} }
} }
...@@ -650,7 +649,7 @@ public class WebServer implements Service { ...@@ -650,7 +649,7 @@ public class WebServer implements Service {
out.close(); out.close();
} }
} catch (Exception e) { } catch (Exception e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
} }
......
...@@ -19,7 +19,7 @@ import java.util.Locale; ...@@ -19,7 +19,7 @@ import java.util.Locale;
import org.h2.bnf.Bnf; import org.h2.bnf.Bnf;
import org.h2.bnf.context.DbContents; import org.h2.bnf.context.DbContents;
import org.h2.bnf.context.DbContextRule; import org.h2.bnf.context.DbContextRule;
import org.h2.message.TraceSystem; import org.h2.message.DbException;
import org.h2.util.New; import org.h2.util.New;
/** /**
...@@ -203,7 +203,7 @@ class WebSession { ...@@ -203,7 +203,7 @@ class WebSession {
m.put("executing", executingStatement == null ? m.put("executing", executingStatement == null ?
"${text.admin.no}" : "${text.admin.yes}"); "${text.admin.no}" : "${text.admin.yes}");
} catch (SQLException e) { } catch (SQLException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
return m; return m;
} }
......
...@@ -22,7 +22,7 @@ import java.util.Properties; ...@@ -22,7 +22,7 @@ import java.util.Properties;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
import org.h2.message.TraceSystem; import org.h2.message.DbException;
import org.h2.mvstore.DataUtils; import org.h2.mvstore.DataUtils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.NetUtils; import org.h2.util.NetUtils;
...@@ -96,7 +96,7 @@ class WebThread extends WebApp implements Runnable { ...@@ -96,7 +96,7 @@ class WebThread extends WebApp implements Runnable {
} }
} }
} catch (Exception e) { } catch (Exception e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
IOUtils.closeSilently(output); IOUtils.closeSilently(output);
IOUtils.closeSilently(input); IOUtils.closeSilently(input);
......
...@@ -27,7 +27,6 @@ import org.h2.engine.SysProperties; ...@@ -27,7 +27,6 @@ import org.h2.engine.SysProperties;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.Utils;
/** /**
* This file system stores files on disk. * This file system stores files on disk.
...@@ -362,7 +361,7 @@ public class FilePathDisk extends FilePath { ...@@ -362,7 +361,7 @@ public class FilePathDisk extends FilePath {
String prefix = new File(fileName).getName(); String prefix = new File(fileName).getName();
File dir; File dir;
if (inTempDir) { if (inTempDir) {
dir = new File(Utils.getProperty("java.io.tmpdir", ".")); dir = new File(System.getProperty("java.io.tmpdir", "."));
} else { } else {
dir = new File(fileName).getAbsoluteFile().getParentFile(); dir = new File(fileName).getAbsoluteFile().getParentFile();
} }
......
...@@ -17,11 +17,11 @@ import java.sql.DriverManager; ...@@ -17,11 +17,11 @@ import java.sql.DriverManager;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.util.Utils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
import org.h2.util.ScriptReader; import org.h2.util.ScriptReader;
...@@ -116,7 +116,7 @@ public class RunScript extends Tool { ...@@ -116,7 +116,7 @@ public class RunScript extends Tool {
showTime = true; showTime = true;
} else if (arg.equals("-driver")) { } else if (arg.equals("-driver")) {
String driver = args[++i]; String driver = args[++i];
Utils.loadUserClass(driver); JdbcUtils.loadUserClass(driver);
} else if (arg.equals("-options")) { } else if (arg.equals("-options")) {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
i++; i++;
......
...@@ -13,7 +13,6 @@ import java.sql.SQLException; ...@@ -13,7 +13,6 @@ import java.sql.SQLException;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.TraceSystem;
import org.h2.server.Service; import org.h2.server.Service;
import org.h2.server.ShutdownHandler; import org.h2.server.ShutdownHandler;
import org.h2.server.TcpServer; import org.h2.server.TcpServer;
...@@ -569,7 +568,7 @@ public class Server extends Tool implements Runnable, ShutdownHandler { ...@@ -569,7 +568,7 @@ public class Server extends Tool implements Runnable, ShutdownHandler {
try { try {
service.listen(); service.listen();
} catch (Exception e) { } catch (Exception e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} }
} }
......
...@@ -128,7 +128,7 @@ public class Shell extends Tool implements Runnable { ...@@ -128,7 +128,7 @@ public class Shell extends Tool implements Runnable {
password = args[++i]; password = args[++i];
} else if (arg.equals("-driver")) { } else if (arg.equals("-driver")) {
String driver = args[++i]; String driver = args[++i];
Utils.loadUserClass(driver); JdbcUtils.loadUserClass(driver);
} else if (arg.equals("-sql")) { } else if (arg.equals("-sql")) {
sql = args[++i]; sql = args[++i];
} else if (arg.equals("-properties")) { } else if (arg.equals("-properties")) {
......
...@@ -32,9 +32,9 @@ import java.util.Map; ...@@ -32,9 +32,9 @@ import java.util.Map;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.Utils;
import org.h2.value.DataType; import org.h2.value.DataType;
/** /**
...@@ -528,7 +528,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -528,7 +528,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
if (o == null || o instanceof byte[]) { if (o == null || o instanceof byte[]) {
return (byte[]) o; return (byte[]) o;
} }
return Utils.serialize(o, null); return JdbcUtils.serialize(o, null);
} }
/** /**
......
...@@ -29,7 +29,7 @@ public class DbDriverActivator implements BundleActivator { ...@@ -29,7 +29,7 @@ public class DbDriverActivator implements BundleActivator {
public void start(BundleContext bundleContext) { public void start(BundleContext bundleContext) {
org.h2.Driver driver = org.h2.Driver.load(); org.h2.Driver driver = org.h2.Driver.load();
try { try {
Utils.loadUserClass(DATASOURCE_FACTORY_CLASS); JdbcUtils.loadUserClass(DATASOURCE_FACTORY_CLASS);
} catch (Exception e) { } catch (Exception e) {
// class not found - don't register // class not found - don't register
return; return;
......
...@@ -6,21 +6,41 @@ ...@@ -6,21 +6,41 @@
*/ */
package org.h2.util; package org.h2.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Properties; import java.util.Properties;
import javax.naming.Context; import javax.naming.Context;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.h2.api.ErrorCode;
import org.h2.api.JavaObjectSerializer;
import org.h2.engine.SysProperties;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.store.DataHandler;
import org.h2.util.Utils.ClassFactory;
/** /**
* This is a utility class with JDBC helper functions. * This is a utility class with JDBC helper functions.
*/ */
public class JdbcUtils { public class JdbcUtils {
/**
* The serializer to use.
*/
public static JavaObjectSerializer serializer;
private static final String[] DRIVERS = { private static final String[] DRIVERS = {
"h2:", "org.h2.Driver", "h2:", "org.h2.Driver",
"Cache:", "com.intersys.jdbc.CacheDriver", "Cache:", "com.intersys.jdbc.CacheDriver",
...@@ -49,10 +69,136 @@ public class JdbcUtils { ...@@ -49,10 +69,136 @@ public class JdbcUtils {
"teradata:", "com.ncr.teradata.TeraDriver", "teradata:", "com.ncr.teradata.TeraDriver",
}; };
private static boolean allowAllClasses;
private static HashSet<String> allowedClassNames;
/**
* In order to manage more than one class loader
*/
private static ArrayList<ClassFactory> userClassFactories =
new ArrayList<ClassFactory>();
private static String[] allowedClassNamePrefixes;
private JdbcUtils() { private JdbcUtils() {
// utility class // utility class
} }
/**
* Add a class factory in order to manage more than one class loader.
*
* @param classFactory An object that implements ClassFactory
*/
public static void addClassFactory(ClassFactory classFactory) {
getUserClassFactories().add(classFactory);
}
/**
* Remove a class factory
*
* @param classFactory Already inserted class factory instance
*/
public static void removeClassFactory(ClassFactory classFactory) {
getUserClassFactories().remove(classFactory);
}
private static ArrayList<ClassFactory> getUserClassFactories() {
if (userClassFactories == null) {
// initially, it is empty
// but Apache Tomcat may clear the fields as well
userClassFactories = new ArrayList<ClassFactory>();
}
return userClassFactories;
}
static {
String clazz = SysProperties.JAVA_OBJECT_SERIALIZER;
if (clazz != null) {
try {
serializer = (JavaObjectSerializer) loadUserClass(clazz).newInstance();
} catch (Exception e) {
throw DbException.convert(e);
}
}
}
/**
* Load a class, but check if it is allowed to load this class first. To
* perform access rights checking, the system property h2.allowedClasses
* needs to be set to a list of class file name prefixes.
*
* @param className the name of the class
* @return the class object
*/
public static Class<?> loadUserClass(String className) {
if (allowedClassNames == null) {
// initialize the static fields
String s = SysProperties.ALLOWED_CLASSES;
ArrayList<String> prefixes = New.arrayList();
boolean allowAll = false;
HashSet<String> classNames = New.hashSet();
for (String p : StringUtils.arraySplit(s, ',', true)) {
if (p.equals("*")) {
allowAll = true;
} else if (p.endsWith("*")) {
prefixes.add(p.substring(0, p.length() - 1));
} else {
classNames.add(p);
}
}
allowedClassNamePrefixes = new String[prefixes.size()];
prefixes.toArray(allowedClassNamePrefixes);
allowAllClasses = allowAll;
allowedClassNames = classNames;
}
if (!allowAllClasses && !allowedClassNames.contains(className)) {
boolean allowed = false;
for (String s : allowedClassNamePrefixes) {
if (className.startsWith(s)) {
allowed = true;
}
}
if (!allowed) {
throw DbException.get(
ErrorCode.ACCESS_DENIED_TO_CLASS_1, className);
}
}
// Use provided class factory first.
for (ClassFactory classFactory : getUserClassFactories()) {
if (classFactory.match(className)) {
try {
Class<?> userClass = classFactory.loadClass(className);
if (!(userClass == null)) {
return userClass;
}
} catch (Exception e) {
throw DbException.get(
ErrorCode.CLASS_NOT_FOUND_1, e, className);
}
}
}
// Use local ClassLoader
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
try {
return Class.forName(
className, true,
Thread.currentThread().getContextClassLoader());
} catch (Exception e2) {
throw DbException.get(
ErrorCode.CLASS_NOT_FOUND_1, e, className);
}
} catch (NoClassDefFoundError e) {
throw DbException.get(
ErrorCode.CLASS_NOT_FOUND_1, e, className);
} catch (Error e) {
// UnsupportedClassVersionError
throw DbException.get(
ErrorCode.GENERAL_ERROR_1, e, className);
}
}
/** /**
* Close a statement without throwing an exception. * Close a statement without throwing an exception.
* *
...@@ -132,7 +278,7 @@ public class JdbcUtils { ...@@ -132,7 +278,7 @@ public class JdbcUtils {
if (StringUtils.isNullOrEmpty(driver)) { if (StringUtils.isNullOrEmpty(driver)) {
JdbcUtils.load(url); JdbcUtils.load(url);
} else { } else {
Class<?> d = Utils.loadUserClass(driver); Class<?> d = loadUserClass(driver);
if (java.sql.Driver.class.isAssignableFrom(d)) { if (java.sql.Driver.class.isAssignableFrom(d)) {
return DriverManager.getConnection(url, prop); return DriverManager.getConnection(url, prop);
} else if (javax.naming.Context.class.isAssignableFrom(d)) { } else if (javax.naming.Context.class.isAssignableFrom(d)) {
...@@ -185,7 +331,81 @@ public class JdbcUtils { ...@@ -185,7 +331,81 @@ public class JdbcUtils {
public static void load(String url) { public static void load(String url) {
String driver = getDriver(url); String driver = getDriver(url);
if (driver != null) { if (driver != null) {
Utils.loadUserClass(driver); loadUserClass(driver);
}
}
/**
* Serialize the object to a byte array, using the serializer specified by
* the connection info if set, or the default serializer.
*
* @param obj the object to serialize
* @param dataHandler provides the object serializer (may be null)
* @return the byte array
*/
public static byte[] serialize(Object obj, DataHandler dataHandler) {
try {
JavaObjectSerializer handlerSerializer = null;
if (dataHandler != null) {
handlerSerializer = dataHandler.getJavaObjectSerializer();
}
if (handlerSerializer != null) {
return handlerSerializer.serialize(obj);
}
if (serializer != null) {
return serializer.serialize(obj);
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out);
os.writeObject(obj);
return out.toByteArray();
} catch (Throwable e) {
throw DbException.get(ErrorCode.SERIALIZATION_FAILED_1, e, e.toString());
}
}
/**
* De-serialize the byte array to an object, eventually using the serializer
* specified by the connection info.
*
* @param data the byte array
* @param dataHandler provides the object serializer (may be null)
* @return the object
* @throws DbException if serialization fails
*/
public static Object deserialize(byte[] data, DataHandler dataHandler) {
try {
JavaObjectSerializer dbJavaObjectSerializer = null;
if (dataHandler != null) {
dbJavaObjectSerializer = dataHandler.getJavaObjectSerializer();
}
if (dbJavaObjectSerializer != null) {
return dbJavaObjectSerializer.deserialize(data);
}
if (serializer != null) {
return serializer.deserialize(data);
}
ByteArrayInputStream in = new ByteArrayInputStream(data);
ObjectInputStream is;
if (SysProperties.USE_THREAD_CONTEXT_CLASS_LOADER) {
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
is = new ObjectInputStream(in) {
@Override
protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
try {
return Class.forName(desc.getName(), true, loader);
} catch (ClassNotFoundException e) {
return super.resolveClass(desc);
}
}
};
} else {
is = new ObjectInputStream(in);
}
return is.readObject();
} catch (Throwable e) {
throw DbException.get(ErrorCode.DESERIALIZATION_FAILED_1, e, e.toString());
} }
} }
......
...@@ -22,8 +22,6 @@ import java.util.Properties; ...@@ -22,8 +22,6 @@ import java.util.Properties;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.Vector; import java.util.Vector;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.h2.message.DbException;
import org.h2.message.TraceSystem;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
/** /**
...@@ -58,7 +56,7 @@ public class SortedProperties extends Properties { ...@@ -58,7 +56,7 @@ public class SortedProperties extends Properties {
try { try {
return Boolean.parseBoolean(value); return Boolean.parseBoolean(value);
} catch (Exception e) { } catch (Exception e) {
TraceSystem.traceThrowable(e); e.printStackTrace();
return def; return def;
} }
} }
...@@ -76,7 +74,7 @@ public class SortedProperties extends Properties { ...@@ -76,7 +74,7 @@ public class SortedProperties extends Properties {
try { try {
return Integer.decode(value); return Integer.decode(value);
} catch (Exception e) { } catch (Exception e) {
TraceSystem.traceThrowable(e); e.printStackTrace();
return def; return def;
} }
} }
...@@ -119,7 +117,7 @@ public class SortedProperties extends Properties { ...@@ -119,7 +117,7 @@ public class SortedProperties extends Properties {
try { try {
w = new OutputStreamWriter(FileUtils.newOutputStream(fileName, false)); w = new OutputStreamWriter(FileUtils.newOutputStream(fileName, false));
} catch (Exception e) { } catch (Exception e) {
throw DbException.convertToIOException(e); throw new IOException(e.toString(), e);
} }
PrintWriter writer = new PrintWriter(new BufferedWriter(w)); PrintWriter writer = new PrintWriter(new BufferedWriter(w));
while (true) { while (true) {
......
...@@ -6,12 +6,16 @@ ...@@ -6,12 +6,16 @@
*/ */
package org.h2.util; package org.h2.util;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* A method call that is executed in a separate thread. If the method throws an * A method call that is executed in a separate thread. If the method throws an
* exception, it is wrapped in a RuntimeException. * exception, it is wrapped in a RuntimeException.
*/ */
public abstract class Task implements Runnable { public abstract class Task implements Runnable {
private static AtomicInteger counter = new AtomicInteger();
/** /**
* A flag indicating the get() method has been called. * A flag indicating the get() method has been called.
*/ */
...@@ -51,7 +55,7 @@ public abstract class Task implements Runnable { ...@@ -51,7 +55,7 @@ public abstract class Task implements Runnable {
* @return this * @return this
*/ */
public Task execute() { public Task execute() {
return execute(getClass().getName()); return execute(getClass().getName() + ":" + counter.getAndIncrement());
} }
/** /**
......
...@@ -6,40 +6,23 @@ ...@@ -6,40 +6,23 @@
*/ */
package org.h2.util; package org.h2.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import org.h2.api.ErrorCode;
import org.h2.api.JavaObjectSerializer;
import org.h2.engine.SysProperties;
import org.h2.message.DbException;
import org.h2.store.DataHandler;
/** /**
* This utility class contains miscellaneous functions. * This utility class contains miscellaneous functions.
*/ */
public class Utils { public class Utils {
/**
* The serializer to use.
*/
public static JavaObjectSerializer serializer;
/** /**
* An 0-size byte array. * An 0-size byte array.
*/ */
...@@ -61,59 +44,10 @@ public class Utils { ...@@ -61,59 +44,10 @@ public class Utils {
private static final HashMap<String, byte[]> RESOURCES = New.hashMap(); private static final HashMap<String, byte[]> RESOURCES = New.hashMap();
private static boolean allowAllClasses;
private static HashSet<String> allowedClassNames;
/**
* In order to manage more than one class loader
*/
private static ArrayList<ClassFactory> userClassFactories =
new ArrayList<ClassFactory>();
private static String[] allowedClassNamePrefixes;
static {
String clazz = SysProperties.JAVA_OBJECT_SERIALIZER;
if (clazz != null) {
try {
serializer = (JavaObjectSerializer) loadUserClass(clazz).newInstance();
} catch (Exception e) {
throw DbException.convert(e);
}
}
}
private Utils() { private Utils() {
// utility class // utility class
} }
/**
* Add a class factory in order to manage more than one class loader.
*
* @param classFactory An object that implements ClassFactory
*/
public static void addClassFactory(ClassFactory classFactory) {
getUserClassFactories().add(classFactory);
}
/**
* Remove a class factory
*
* @param classFactory Already inserted class factory instance
*/
public static void removeClassFactory(ClassFactory classFactory) {
getUserClassFactories().remove(classFactory);
}
private static ArrayList<ClassFactory> getUserClassFactories() {
if (userClassFactories == null) {
// initially, it is empty
// but Apache Tomcat may clear the fields as well
userClassFactories = new ArrayList<ClassFactory>();
}
return userClassFactories;
}
private static int readInt(byte[] buff, int pos) { private static int readInt(byte[] buff, int pos) {
return (buff[pos++] << 24) + return (buff[pos++] << 24) +
((buff[pos++] & 0xff) << 16) + ((buff[pos++] & 0xff) << 16) +
...@@ -332,94 +266,6 @@ public class Utils { ...@@ -332,94 +266,6 @@ public class Utils {
return copy; return copy;
} }
/**
* Serialize the object to a byte array, using the serializer specified by
* the connection info if set, or the default serializer.
*
* @param obj the object to serialize
* @param dataHandler provides the object serializer (may be null)
* @return the byte array
*/
public static byte[] serialize(Object obj, DataHandler dataHandler) {
try {
JavaObjectSerializer handlerSerializer = null;
if (dataHandler != null) {
handlerSerializer = dataHandler.getJavaObjectSerializer();
}
if (handlerSerializer != null) {
return handlerSerializer.serialize(obj);
}
if (serializer != null) {
return serializer.serialize(obj);
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out);
os.writeObject(obj);
return out.toByteArray();
} catch (Throwable e) {
throw DbException.get(ErrorCode.SERIALIZATION_FAILED_1, e, e.toString());
}
}
/**
* De-serialize the byte array to an object.
*
* @param data the byte array
* @return the object
* @throws DbException if serialization fails
*
* @deprecated use {@link #deserialize(byte[], DataHandler)} instead
*/
@Deprecated
public static Object deserialize(byte[] data) {
return deserialize(data, null);
}
/**
* De-serialize the byte array to an object, eventually using the serializer
* specified by the connection info.
*
* @param data the byte array
* @param dataHandler provides the object serializer (may be null)
* @return the object
* @throws DbException if serialization fails
*/
public static Object deserialize(byte[] data, DataHandler dataHandler) {
try {
JavaObjectSerializer dbJavaObjectSerializer = null;
if (dataHandler != null) {
dbJavaObjectSerializer = dataHandler.getJavaObjectSerializer();
}
if (dbJavaObjectSerializer != null) {
return dbJavaObjectSerializer.deserialize(data);
}
if (serializer != null) {
return serializer.deserialize(data);
}
ByteArrayInputStream in = new ByteArrayInputStream(data);
ObjectInputStream is;
if (SysProperties.USE_THREAD_CONTEXT_CLASS_LOADER) {
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
is = new ObjectInputStream(in) {
@Override
protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
try {
return Class.forName(desc.getName(), true, loader);
} catch (ClassNotFoundException e) {
return super.resolveClass(desc);
}
}
};
} else {
is = new ObjectInputStream(in);
}
return is.readObject();
} catch (Throwable e) {
throw DbException.get(ErrorCode.DESERIALIZATION_FAILED_1, e, e.toString());
}
}
/** /**
* Calculate the hash code of the given object. The object may be null. * Calculate the hash code of the given object. The object may be null.
* *
...@@ -605,83 +451,6 @@ public class Utils { ...@@ -605,83 +451,6 @@ public class Utils {
return top1 == top2; return top1 == top2;
} }
/**
* Load a class, but check if it is allowed to load this class first. To
* perform access rights checking, the system property h2.allowedClasses
* needs to be set to a list of class file name prefixes.
*
* @param className the name of the class
* @return the class object
*/
public static Class<?> loadUserClass(String className) {
if (allowedClassNames == null) {
// initialize the static fields
String s = SysProperties.ALLOWED_CLASSES;
ArrayList<String> prefixes = New.arrayList();
boolean allowAll = false;
HashSet<String> classNames = New.hashSet();
for (String p : StringUtils.arraySplit(s, ',', true)) {
if (p.equals("*")) {
allowAll = true;
} else if (p.endsWith("*")) {
prefixes.add(p.substring(0, p.length() - 1));
} else {
classNames.add(p);
}
}
allowedClassNamePrefixes = new String[prefixes.size()];
prefixes.toArray(allowedClassNamePrefixes);
allowAllClasses = allowAll;
allowedClassNames = classNames;
}
if (!allowAllClasses && !allowedClassNames.contains(className)) {
boolean allowed = false;
for (String s : allowedClassNamePrefixes) {
if (className.startsWith(s)) {
allowed = true;
}
}
if (!allowed) {
throw DbException.get(
ErrorCode.ACCESS_DENIED_TO_CLASS_1, className);
}
}
// Use provided class factory first.
for (ClassFactory classFactory : getUserClassFactories()) {
if (classFactory.match(className)) {
try {
Class<?> userClass = classFactory.loadClass(className);
if (!(userClass == null)) {
return userClass;
}
} catch (Exception e) {
throw DbException.get(
ErrorCode.CLASS_NOT_FOUND_1, e, className);
}
}
}
// Use local ClassLoader
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
try {
return Class.forName(
className, true,
Thread.currentThread().getContextClassLoader());
} catch (Exception e2) {
throw DbException.get(
ErrorCode.CLASS_NOT_FOUND_1, e, className);
}
} catch (NoClassDefFoundError e) {
throw DbException.get(
ErrorCode.CLASS_NOT_FOUND_1, e, className);
} catch (Error e) {
// UnsupportedClassVersionError
throw DbException.get(
ErrorCode.GENERAL_ERROR_1, e, className);
}
}
/** /**
* Get a resource from the resource map. * Get a resource from the resource map.
* *
......
...@@ -9,9 +9,10 @@ package org.h2.value; ...@@ -9,9 +9,10 @@ package org.h2.value;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Comparator; import java.util.Comparator;
import java.util.Locale; import java.util.Locale;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.util.JdbcUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.util.Utils;
/** /**
* An implementation of CompareMode that uses the ICU4J Collator. * An implementation of CompareMode that uses the ICU4J Collator.
...@@ -45,7 +46,7 @@ public class CompareModeIcu4J extends CompareMode { ...@@ -45,7 +46,7 @@ public class CompareModeIcu4J extends CompareMode {
private static Comparator<String> getIcu4jCollator(String name, int strength) { private static Comparator<String> getIcu4jCollator(String name, int strength) {
try { try {
Comparator<String> result = null; Comparator<String> result = null;
Class<?> collatorClass = Utils.loadUserClass( Class<?> collatorClass = JdbcUtils.loadUserClass(
"com.ibm.icu.text.Collator"); "com.ibm.icu.text.Collator");
Method getInstanceMethod = collatorClass.getMethod( Method getInstanceMethod = collatorClass.getMethod(
"getInstance", Locale.class); "getInstance", Locale.class);
......
...@@ -33,6 +33,7 @@ import org.h2.jdbc.JdbcClob; ...@@ -33,6 +33,7 @@ import org.h2.jdbc.JdbcClob;
import org.h2.jdbc.JdbcConnection; import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.JdbcUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.Utils; import org.h2.util.Utils;
...@@ -175,7 +176,7 @@ public class DataType { ...@@ -175,7 +176,7 @@ public class DataType {
static { static {
Class<?> g; Class<?> g;
try { try {
g = Utils.loadUserClass(GEOMETRY_CLASS_NAME); g = JdbcUtils.loadUserClass(GEOMETRY_CLASS_NAME);
} catch (Exception e) { } catch (Exception e) {
// class is not in the classpath - ignore // class is not in the classpath - ignore
g = null; g = null;
...@@ -1194,7 +1195,7 @@ public class DataType { ...@@ -1194,7 +1195,7 @@ public class DataType {
return new JdbcClob(conn, v, 0); return new JdbcClob(conn, v, 0);
} }
if (v.getType() == Value.JAVA_OBJECT) { if (v.getType() == Value.JAVA_OBJECT) {
Object o = SysProperties.serializeJavaObject ? Utils.deserialize(v.getBytes(), Object o = SysProperties.serializeJavaObject ? JdbcUtils.deserialize(v.getBytes(),
conn.getSession().getDataHandler()) : v.getObject(); conn.getSession().getDataHandler()) : v.getObject();
if (paramClass.isAssignableFrom(o.getClass())) { if (paramClass.isAssignableFrom(o.getClass())) {
return o; return o;
......
...@@ -24,7 +24,6 @@ import org.h2.api.ErrorCode; ...@@ -24,7 +24,6 @@ import org.h2.api.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.SessionInterface; import org.h2.engine.SessionInterface;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.TraceSystem;
import org.h2.mvstore.DataUtils; import org.h2.mvstore.DataUtils;
import org.h2.security.SHA256; import org.h2.security.SHA256;
import org.h2.store.Data; import org.h2.store.Data;
...@@ -32,6 +31,7 @@ import org.h2.store.DataReader; ...@@ -32,6 +31,7 @@ import org.h2.store.DataReader;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.DateTimeUtils; import org.h2.util.DateTimeUtils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.NetUtils; import org.h2.util.NetUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
...@@ -321,7 +321,7 @@ public class Transfer { ...@@ -321,7 +321,7 @@ public class Transfer {
socket.close(); socket.close();
} }
} catch (IOException e) { } catch (IOException e) {
TraceSystem.traceThrowable(e); DbException.traceThrowable(e);
} finally { } finally {
socket = null; socket = null;
} }
...@@ -665,7 +665,7 @@ public class Transfer { ...@@ -665,7 +665,7 @@ public class Transfer {
Class<?> componentType = Object.class; Class<?> componentType = Object.class;
if (len < 0) { if (len < 0) {
len = -(len + 1); len = -(len + 1);
componentType = Utils.loadUserClass(readString()); componentType = JdbcUtils.loadUserClass(readString());
} }
Value[] list = new Value[len]; Value[] list = new Value[len];
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
......
...@@ -27,6 +27,7 @@ import org.h2.message.DbException; ...@@ -27,6 +27,7 @@ import org.h2.message.DbException;
import org.h2.store.DataHandler; import org.h2.store.DataHandler;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.DateTimeUtils; import org.h2.util.DateTimeUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.util.Utils; import org.h2.util.Utils;
...@@ -817,7 +818,7 @@ public abstract class Value { ...@@ -817,7 +818,7 @@ public abstract class Value {
case BYTES: case BYTES:
return ValueGeometry.get(getBytesNoCopy()); return ValueGeometry.get(getBytesNoCopy());
case JAVA_OBJECT: case JAVA_OBJECT:
Object object = Utils.deserialize(getBytesNoCopy(), getDataHandler()); Object object = JdbcUtils.deserialize(getBytesNoCopy(), getDataHandler());
if (DataType.isGeometry(object)) { if (DataType.isGeometry(object)) {
return ValueGeometry.getFromGeometry(object); return ValueGeometry.getFromGeometry(object);
} }
......
...@@ -12,6 +12,7 @@ import java.sql.Types; ...@@ -12,6 +12,7 @@ import java.sql.Types;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
import org.h2.store.DataHandler; import org.h2.store.DataHandler;
import org.h2.util.JdbcUtils;
import org.h2.util.Utils; import org.h2.util.Utils;
/** /**
...@@ -45,7 +46,7 @@ public class ValueJavaObject extends ValueBytes { ...@@ -45,7 +46,7 @@ public class ValueJavaObject extends ValueBytes {
ValueJavaObject obj; ValueJavaObject obj;
if (SysProperties.serializeJavaObject) { if (SysProperties.serializeJavaObject) {
if (b == null) { if (b == null) {
b = Utils.serialize(javaObject, dataHandler); b = JdbcUtils.serialize(javaObject, dataHandler);
} }
obj = new ValueJavaObject(b, dataHandler); obj = new ValueJavaObject(b, dataHandler);
} else { } else {
...@@ -65,7 +66,7 @@ public class ValueJavaObject extends ValueBytes { ...@@ -65,7 +66,7 @@ public class ValueJavaObject extends ValueBytes {
@Override @Override
public void set(PreparedStatement prep, int parameterIndex) public void set(PreparedStatement prep, int parameterIndex)
throws SQLException { throws SQLException {
Object obj = Utils.deserialize(getBytesNoCopy(), getDataHandler()); Object obj = JdbcUtils.deserialize(getBytesNoCopy(), getDataHandler());
prep.setObject(parameterIndex, obj, Types.JAVA_OBJECT); prep.setObject(parameterIndex, obj, Types.JAVA_OBJECT);
} }
...@@ -95,7 +96,7 @@ public class ValueJavaObject extends ValueBytes { ...@@ -95,7 +96,7 @@ public class ValueJavaObject extends ValueBytes {
@Override @Override
public byte[] getBytesNoCopy() { public byte[] getBytesNoCopy() {
if (value == null) { if (value == null) {
value = Utils.serialize(javaObject, null); value = JdbcUtils.serialize(javaObject, null);
} }
return value; return value;
} }
...@@ -163,7 +164,7 @@ public class ValueJavaObject extends ValueBytes { ...@@ -163,7 +164,7 @@ public class ValueJavaObject extends ValueBytes {
@Override @Override
public Object getObject() { public Object getObject() {
if (javaObject == null) { if (javaObject == null) {
javaObject = Utils.deserialize(value, getDataHandler()); javaObject = JdbcUtils.deserialize(value, getDataHandler());
} }
return javaObject; return javaObject;
} }
......
...@@ -36,7 +36,6 @@ import org.h2.util.IOUtils; ...@@ -36,7 +36,6 @@ import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.util.Task; import org.h2.util.Task;
import org.h2.util.Utils;
/** /**
* Tests LOB and CLOB data types. * Tests LOB and CLOB data types.
...@@ -1430,7 +1429,7 @@ public class TestLob extends TestBase { ...@@ -1430,7 +1429,7 @@ public class TestLob extends TestBase {
conn.createStatement().execute("drop table test"); conn.createStatement().execute("drop table test");
stat.execute("create table test(value other)"); stat.execute("create table test(value other)");
prep = conn.prepareStatement("insert into test values(?)"); prep = conn.prepareStatement("insert into test values(?)");
prep.setObject(1, Utils.serialize("", conn.getSession().getDataHandler())); prep.setObject(1, JdbcUtils.serialize("", conn.getSession().getDataHandler()));
prep.execute(); prep.execute();
rs = stat.executeQuery("select value from test"); rs = stat.executeQuery("select value from test");
while (rs.next()) { while (rs.next()) {
......
...@@ -27,6 +27,7 @@ import org.h2.api.ErrorCode; ...@@ -27,6 +27,7 @@ import org.h2.api.ErrorCode;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.Utils; import org.h2.util.Utils;
/** /**
...@@ -375,7 +376,7 @@ public class TestCallableStatement extends TestBase { ...@@ -375,7 +376,7 @@ public class TestCallableStatement extends TestBase {
private void testClassLoader(Connection conn) throws SQLException { private void testClassLoader(Connection conn) throws SQLException {
Utils.ClassFactory myFactory = new TestClassFactory(); Utils.ClassFactory myFactory = new TestClassFactory();
Utils.addClassFactory(myFactory); JdbcUtils.addClassFactory(myFactory);
try { try {
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("CREATE ALIAS T_CLASSLOADER FOR \"TestClassFactory.testClassF\""); stat.execute("CREATE ALIAS T_CLASSLOADER FOR \"TestClassFactory.testClassF\"");
...@@ -383,7 +384,7 @@ public class TestCallableStatement extends TestBase { ...@@ -383,7 +384,7 @@ public class TestCallableStatement extends TestBase {
assertTrue(rs.next()); assertTrue(rs.next());
assertEquals(false, rs.getBoolean(1)); assertEquals(false, rs.getBoolean(1));
} finally { } finally {
Utils.removeClassFactory(myFactory); JdbcUtils.removeClassFactory(myFactory);
} }
} }
......
...@@ -13,7 +13,7 @@ import java.sql.Statement; ...@@ -13,7 +13,7 @@ import java.sql.Statement;
import java.sql.Types; import java.sql.Types;
import org.h2.api.JavaObjectSerializer; import org.h2.api.JavaObjectSerializer;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.Utils; import org.h2.util.JdbcUtils;
/** /**
* Tests {@link JavaObjectSerializer}. * Tests {@link JavaObjectSerializer}.
...@@ -47,7 +47,7 @@ public class TestJavaObjectSerializer extends TestBase { ...@@ -47,7 +47,7 @@ public class TestJavaObjectSerializer extends TestBase {
} }
private void testStaticGlobalSerializer() throws Exception { private void testStaticGlobalSerializer() throws Exception {
Utils.serializer = new JavaObjectSerializer() { JdbcUtils.serializer = new JavaObjectSerializer() {
@Override @Override
public byte[] serialize(Object obj) throws Exception { public byte[] serialize(Object obj) throws Exception {
assertEquals(100500, ((Integer) obj).intValue()); assertEquals(100500, ((Integer) obj).intValue());
...@@ -86,7 +86,7 @@ public class TestJavaObjectSerializer extends TestBase { ...@@ -86,7 +86,7 @@ public class TestJavaObjectSerializer extends TestBase {
conn.close(); conn.close();
deleteDb("javaSerializer"); deleteDb("javaSerializer");
} finally { } finally {
Utils.serializer = null; JdbcUtils.serializer = null;
} }
} }
......
...@@ -8,8 +8,8 @@ package org.h2.test.unit; ...@@ -8,8 +8,8 @@ package org.h2.test.unit;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.JdbcUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.util.Utils;
/** /**
* Tests the ability to deserialize objects that are not part of the system * Tests the ability to deserialize objects that are not part of the system
...@@ -46,7 +46,7 @@ public class TestObjectDeserialization extends TestBase { ...@@ -46,7 +46,7 @@ public class TestObjectDeserialization extends TestBase {
usesThreadContextClassLoader = false; usesThreadContextClassLoader = false;
Thread.currentThread().setContextClassLoader(new TestClassLoader()); Thread.currentThread().setContextClassLoader(new TestClassLoader());
try { try {
Utils.deserialize(StringUtils.convertHexToBytes(OBJECT), null); JdbcUtils.deserialize(StringUtils.convertHexToBytes(OBJECT), null);
fail(); fail();
} catch (DbException e) { } catch (DbException e) {
// expected // expected
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论