diff options
author | Eike Stepper | 2013-10-14 12:41:20 +0000 |
---|---|---|
committer | Eike Stepper | 2013-10-14 12:41:20 +0000 |
commit | 632884c15c9e7ae97940cb3949585954d981ccf8 (patch) | |
tree | 4a259cc6587ca62c4193ab9d178c03ab76f6ae74 | |
parent | 2ec08800feb6d88615bcd48c3db279542de28cd2 (diff) | |
download | cdo-632884c15c9e7ae97940cb3949585954d981ccf8.tar.gz cdo-632884c15c9e7ae97940cb3949585954d981ccf8.tar.xz cdo-632884c15c9e7ae97940cb3949585954d981ccf8.zip |
[419356] Handle exception during asynchronous queries in result order
https://bugs.eclipse.org/bugs/show_bug.cgi?id=419356
25 files changed, 413 insertions, 89 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/.settings/.api_filters b/plugins/org.eclipse.emf.cdo.common/.settings/.api_filters index 6f5fed218e..1fcf68beb2 100644 --- a/plugins/org.eclipse.emf.cdo.common/.settings/.api_filters +++ b/plugins/org.eclipse.emf.cdo.common/.settings/.api_filters @@ -140,6 +140,22 @@ </message_arguments> </filter> </resource> + <resource path="src/org/eclipse/emf/cdo/common/protocol/CDODataInput.java" type="org.eclipse.emf.cdo.common.protocol.CDODataInput"> + <filter id="571473929"> + <message_arguments> + <message_argument value="ExtendedDataInput"/> + <message_argument value="CDODataInput"/> + </message_arguments> + </filter> + </resource> + <resource path="src/org/eclipse/emf/cdo/common/protocol/CDODataOutput.java" type="org.eclipse.emf.cdo.common.protocol.CDODataOutput"> + <filter id="571473929"> + <message_arguments> + <message_argument value="ExtendedDataOutput"/> + <message_argument value="CDODataOutput"/> + </message_arguments> + </filter> + </resource> <resource path="src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java" type="org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants"> <filter id="388194388"> <message_arguments> diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java index d8c3acd472..a447d83d6f 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java @@ -523,6 +523,11 @@ public final class CDOModelUtil implements CDOModelConstants return CDOType.FEATURE_MAP_ENTRY; } + if (object instanceof Throwable) + { + return CDOType.EXCEPTION; + } + throw new IllegalArgumentException("Object type " + objectClass.getName() + " is not supported."); } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOType.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOType.java index a63208421c..39af51956a 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOType.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOType.java @@ -137,6 +137,11 @@ public interface CDOType */ public static final CDOType FEATURE_MAP_ENTRY = org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl.FEATURE_MAP_ENTRY; + /** + * @since 4.3 + */ + public static final CDOType EXCEPTION = org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl.EXCEPTION; + public String getName(); /** diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java index 2d9416ce50..2b2dd3bc92 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java @@ -28,7 +28,9 @@ public interface CDOProtocolConstants /** * @since 4.2 */ - public static final int PROTOCOL_VERSION = 16; // Last update for permission transfers + public static final int PROTOCOL_VERSION = 17; // Make query fail in sequence + + // public static final int PROTOCOL_VERSION = 16; // Last update for permission transfers // ////////////////////////////////////////////////////////////////////// // Signal IDs @@ -283,6 +285,21 @@ public interface CDOProtocolConstants // ////////////////////////////////////////////////////////////////////// // Query Support + /** + * @since 4.3 + */ + public static final byte QUERY_RESULT_EXCEPTION = 0; + + /** + * @since 4.3 + */ + public static final byte QUERY_RESULT_PRIMITIVE = 1; + + /** + * @since 4.3 + */ + public static final byte QUERY_RESULT_REVISION = 2; + public static final String QUERY_LANGUAGE_RESOURCES = "resources"; //$NON-NLS-1$ public static final String QUERY_LANGUAGE_RESOURCES_FOLDER_ID = "folder"; //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/util/CDOQueryQueue.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/util/CDOQueryQueue.java index 672824cb86..310f42e1c6 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/util/CDOQueryQueue.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/util/CDOQueryQueue.java @@ -56,7 +56,6 @@ public class CDOQueryQueue<E> implements Queue<E>, Closeable { if (!closed) { - closed = true; queue.add(QUEUE_CLOSED); } } @@ -72,7 +71,8 @@ public class CDOQueryQueue<E> implements Queue<E>, Closeable public boolean add(E e) { - return queue.add(new QueueEntry<E>(e)); + QueueEntry<E> entry = new QueueEntry<E>(e); + return queue.add(entry); } public void clear() @@ -216,7 +216,17 @@ public class CDOQueryQueue<E> implements Queue<E>, Closeable private E checkObject(QueueEntry<E> entry) { - if (entry == null || entry == QUEUE_CLOSED) + if (entry == QUEUE_CLOSED) + { + synchronized (closeLock) + { + closed = true; + } + + return null; + } + + if (entry == null) { return null; } @@ -261,7 +271,8 @@ public class CDOQueryQueue<E> implements Queue<E>, Closeable { throw WrappedException.wrap((Exception)exception); } - else if (exception instanceof Error) + + if (exception instanceof Error) { throw (Error)exception; } @@ -281,16 +292,6 @@ public class CDOQueryQueue<E> implements Queue<E>, Closeable public int compareTo(QueueEntry<E> o) { - if (getException() != null) - { - return -1; - } - - if (o.getException() != null) - { - return 1; - } - if (this == o) { return 0; diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOTypeImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOTypeImpl.java index 1c083c0abf..3e225d6918 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOTypeImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOTypeImpl.java @@ -880,6 +880,21 @@ public abstract class CDOTypeImpl implements CDOType } }; + public static final CDOType EXCEPTION = new ObjectType("EXCEPTION", -9) //$NON-NLS-1$ + { + @Override + protected void doWriteValue(CDODataOutput out, Object value) throws IOException + { + out.writeException((Throwable)value); + } + + @Override + protected Throwable doReadValue(CDODataInput in) throws IOException + { + return in.readException(); + } + }; + private String name; private byte typeID; diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractQueryResult.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractQueryResult.java index 255af23a42..9236eb1ae9 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractQueryResult.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractQueryResult.java @@ -16,6 +16,8 @@ import org.eclipse.emf.cdo.common.util.BlockingCloseableIterator; import org.eclipse.emf.cdo.common.util.CDOQueryInfo; import org.eclipse.emf.cdo.common.util.CDOQueryQueue; +import org.eclipse.net4j.util.WrappedException; + /** * If the meaning of this type isn't clear, there really should be more of a description here... * @@ -86,7 +88,19 @@ public class AbstractQueryResult<T> implements BlockingCloseableIterator<T> @SuppressWarnings("unchecked") public T next() { - return (T)queueItr.next(); + Object element = queueItr.next(); + + if (element instanceof Throwable) + { + if (element instanceof Error) + { + throw (Error)element; + } + + throw WrappedException.wrap((Exception)element); + } + + return (T)element; } public void remove() diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/protocol/CDODataOutputImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/protocol/CDODataOutputImpl.java index 2902a6d46e..09523a568a 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/protocol/CDODataOutputImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/protocol/CDODataOutputImpl.java @@ -504,6 +504,7 @@ public class CDODataOutputImpl extends ExtendedDataOutput.Delegating implements public void writeCDORevisionOrPrimitive(Object value) throws IOException { + // Value conversions if (value == null) { value = CDOID.NULL; @@ -517,11 +518,16 @@ public class CDODataOutputImpl extends ExtendedDataOutput.Delegating implements value = ((CDORevision)value).getID(); } + // Type determination CDOType type = null; if (value instanceof CDOID) { type = CDOType.OBJECT; } + else if (value instanceof Throwable) + { + type = CDOType.EXCEPTION; + } else { type = CDOModelUtil.getPrimitiveType(value.getClass()); diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/QueryRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/QueryRequest.java index 086f34249e..b3f8cce85c 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/QueryRequest.java +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/QueryRequest.java @@ -87,7 +87,7 @@ public class QueryRequest extends CDOClientRequest<Boolean> } resultQueue.add(element); - numberOfObjectsReceived++; + ++numberOfObjectsReceived; } if (TRACER.isEnabled()) diff --git a/plugins/org.eclipse.emf.cdo.server.lissome/src/org/eclipse/emf/cdo/server/internal/lissome/LissomeFileHandle.java b/plugins/org.eclipse.emf.cdo.server.lissome/src/org/eclipse/emf/cdo/server/internal/lissome/LissomeFileHandle.java index 2d3b11bf51..455c325942 100644 --- a/plugins/org.eclipse.emf.cdo.server.lissome/src/org/eclipse/emf/cdo/server/internal/lissome/LissomeFileHandle.java +++ b/plugins/org.eclipse.emf.cdo.server.lissome/src/org/eclipse/emf/cdo/server/internal/lissome/LissomeFileHandle.java @@ -256,6 +256,11 @@ public class LissomeFileHandle extends DataInputOutputFile implements CDODataInp return in().readEnum(type); } + public Throwable readException() throws IOException + { + return in().readException(); + } + public CDOPackageUnit readCDOPackageUnit(ResourceSet resourceSet) throws IOException { return in().readCDOPackageUnit(resourceSet); @@ -493,6 +498,11 @@ public class LissomeFileHandle extends DataInputOutputFile implements CDODataInp out().writeEnum(literal); } + public void writeException(Throwable t) throws IOException + { + out().writeException(t); + } + public void writeCDOPackageUnit(CDOPackageUnit packageUnit, boolean withPackages) throws IOException { out().writeCDOPackageUnit(packageUnit, withPackages); diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/QueryIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/QueryIndication.java index c25fe290a7..e8e927d64f 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/QueryIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/QueryIndication.java @@ -68,12 +68,24 @@ public class QueryIndication extends CDOServerReadIndication flushUnlessDisabled(); int numberOfResults = 0; - while (queryResult.hasNext()) + for (;;) { - Object object = queryResult.next(); + Object object; + + try + { + if (!queryResult.hasNext()) + { + break; + } + + object = queryResult.next(); + } + catch (Throwable ex) + { + object = ex; + } - // Object to return - numberOfResults++; out.writeBoolean(true); if (xrefs) @@ -84,11 +96,29 @@ public class QueryIndication extends CDOServerReadIndication else { out.writeCDORevisionOrPrimitive(object); + + if (object instanceof Throwable) + { + break; + } } - if (queryResult.peek() == null) + ++numberOfResults; + + try + { + if (queryResult.peek() == null) + { + flushUnlessDisabled(); + } + } + catch (IOException ex) + { + throw ex; + } + catch (Throwable ex) { - flushUnlessDisabled(); + // Ignore execution exceptions from peek(); they're handle } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryManager.java index d2671bb16b..765f9703e7 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryManager.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryManager.java @@ -14,6 +14,7 @@ package org.eclipse.emf.cdo.internal.server; import org.eclipse.emf.cdo.common.branch.CDOBranch; import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.util.CDOQueryInfo; +import org.eclipse.emf.cdo.common.util.CDOQueryQueue; import org.eclipse.emf.cdo.internal.server.bundle.OM; import org.eclipse.emf.cdo.server.IQueryContext; import org.eclipse.emf.cdo.server.IQueryHandler; @@ -276,30 +277,47 @@ public class QueryManager extends Lifecycle implements InternalQueryManager throw new IllegalStateException("Maximum number of results exceeded"); //$NON-NLS-1$ } - queryResult.getQueue().add(object); + CDOQueryQueue<Object> queue = queryResult.getQueue(); + queue.add(object); + return !cancelled && --resultCount > 0; } public void run() { + CDOQueryQueue<Object> queue = queryResult.getQueue(); + InternalSession session = queryResult.getView().getSession(); StoreThreadLocal.setSession(session); try { started = true; + CDOQueryInfo info = queryResult.getQueryInfo(); resultCount = info.getMaxResults() < 0 ? Integer.MAX_VALUE : info.getMaxResults(); IQueryHandler handler = repository.getQueryHandler(info); - handler.executeQuery(info, this); + + try + { + handler.executeQuery(info, this); + } + catch (Throwable executionException) + { + // int xxx; + // ConcurrencyUtil.sleep(2000); + + addResult(executionException); + return; + } } - catch (Throwable exception) + catch (Throwable initializationException) { - queryResult.getQueue().setException(exception); + queue.setException(initializationException); } finally { - queryResult.getQueue().close(); + queue.close(); unregister(this); StoreThreadLocal.release(); } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java index 60f673f20a..5e64a55a3a 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java @@ -71,6 +71,15 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl List<Object> filters = new ArrayList<Object>(); Object context = info.getParameters().get("context"); //$NON-NLS-1$ Long sleep = (Long)info.getParameters().get("sleep"); //$NON-NLS-1$ + Integer integers = (Integer)info.getParameters().get("integers"); //$NON-NLS-1$ + Integer error = (Integer)info.getParameters().get("error"); //$NON-NLS-1$ + + if (integers != null) + { + executeQuery(integers, error, queryContext); + return; + } + if (context != null) { if (context instanceof EClass) @@ -94,6 +103,7 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl } } + int i = 0; for (InternalCDORevision revision : getStore().getCurrentRevisions()) { if (sleep != null) @@ -108,19 +118,10 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl } } - boolean valid = true; - - for (Object filter : filters) + if (isValid(revision, filters)) { - if (!filter.equals(revision)) - { - valid = false; - break; - } - } + throwExceptionAt(error, ++i); - if (valid) - { if (!queryContext.addResult(revision)) { // No more results allowed @@ -129,6 +130,41 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl } } } + + private void throwExceptionAt(Integer error, int i) + { + if (error != null && i == error) + { + throw new RuntimeException("Simulated problem in query execution at result " + i); + } + } + + private void executeQuery(int integers, Integer error, IQueryContext queryContext) + { + for (int i = 1; i <= integers; ++i) + { + throwExceptionAt(error, i); + + if (!queryContext.addResult(i)) + { + // No more results allowed + break; + } + } + } + + private boolean isValid(InternalCDORevision revision, List<Object> filters) + { + for (Object filter : filters) + { + if (!filter.equals(revision)) + { + return false; + } + } + + return true; + } }; private List<InternalCDORevision> newRevisions = new ArrayList<InternalCDORevision>(); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MEMStoreQueryTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MEMStoreQueryTest.java index ab8f99c9e6..fc86c90b0c 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MEMStoreQueryTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/MEMStoreQueryTest.java @@ -35,7 +35,7 @@ import java.util.Set; @Requires("MEM") public class MEMStoreQueryTest extends AbstractCDOTest { - public void testMEMStoreBasicQuery() throws Exception + public void testBasicQuery() throws Exception { Set<Object> objects = new HashSet<Object>(); CDOSession session = openSession(); @@ -69,7 +69,41 @@ public class MEMStoreQueryTest extends AbstractCDOTest session.close(); } - public void testMEMStoreBasicQuery_EClassParameter() throws Exception + public void testQueryException() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + CDOQuery query = transaction.createQuery("TEST", "QUERYSTRING"); + query.setParameter("error", 5000); + query.setParameter("integers", 10000); + + CloseableIterator<Object> it = query.getResultAsync(Object.class); + int i = 0; + + for (;;) + { + ++i; + + try + { + if (!it.hasNext()) + { + break; + } + } + catch (Exception expected) + { + expected.printStackTrace(); + break; + } + + it.next(); + } + + assertEquals("Query should have stopped at the 5000th result", 5000, i); + } + + public void testBasicQuery_EClassParameter() throws Exception { Set<Object> objects = new HashSet<Object>(); CDOSession session = openSession(); @@ -102,7 +136,7 @@ public class MEMStoreQueryTest extends AbstractCDOTest session.close(); } - public void testMEMStoreQueryCancel_successful() throws Exception + public void testQueryCancel_successful() throws Exception { CDOTransaction transaction = initialize(500); CDOQuery query = transaction.createQuery("TEST", "QUERYSTRING"); @@ -124,7 +158,7 @@ public class MEMStoreQueryTest extends AbstractCDOTest session.close(); } - public void testMEMStoreQueryCancel_ViewClose() throws Exception + public void testQueryCancel_ViewClose() throws Exception { CDOTransaction transaction = initialize(500); CDOQuery query = transaction.createQuery("TEST", "QUERYSTRING"); @@ -144,7 +178,7 @@ public class MEMStoreQueryTest extends AbstractCDOTest session.close(); } - public void testMEMStoreQueryCancel_SessionClose() throws Exception + public void testQueryCancel_SessionClose() throws Exception { CDOTransaction transaction = initialize(500); CDOQuery query = transaction.createQuery("TEST", "QUERYSTRING"); @@ -162,7 +196,7 @@ public class MEMStoreQueryTest extends AbstractCDOTest }.assertNoTimeOut(); } - public void testMEMStoreQueryAsync_UnsupportedLanguage() throws Exception + public void testQueryAsync_UnsupportedLanguage() throws Exception { CDOTransaction transaction = initialize(100); CDOQuery query = transaction.createQuery("TESTss", "QUERYSTRING"); @@ -178,7 +212,7 @@ public class MEMStoreQueryTest extends AbstractCDOTest } } - public void testMEMStoreQuerySync_UnsupportedLanguage() throws Exception + public void testQuerySync_UnsupportedLanguage() throws Exception { CDOTransaction transaction = initialize(100); CDOQuery query = transaction.createQuery("TESTss", "QUERYSTRING"); diff --git a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java index b5b9ce191e..b073c1c0dc 100644 --- a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java +++ b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java @@ -143,6 +143,11 @@ public abstract class AbstractOMTest extends TestCase return null; } + protected boolean logSetUpAndTearDown() + { + return false; + } + @Override public void setUp() throws Exception { @@ -165,21 +170,36 @@ public abstract class AbstractOMTest extends TestCase IOUtil.OUT().println("*******************************************************"); //$NON-NLS-1$ } + if (!logSetUpAndTearDown()) + { + disableConsole(); + } + super.setUp(); doSetUp(); - if (!SUPPRESS_OUTPUT) + if (!SUPPRESS_OUTPUT && logSetUpAndTearDown()) { IOUtil.OUT().println(); IOUtil.OUT().println("------------------------ START ------------------------"); //$NON-NLS-1$ } + + enableConsole(); } @Override public void tearDown() throws Exception { - enableConsole(); - if (!SUPPRESS_OUTPUT) + if (logSetUpAndTearDown()) + { + enableConsole(); + } + else + { + disableConsole(); + } + + if (!SUPPRESS_OUTPUT && logSetUpAndTearDown()) { IOUtil.OUT().println("------------------------- END -------------------------"); //$NON-NLS-1$ IOUtil.OUT().println(); diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/DataInputExtender.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/DataInputExtender.java index 1611290d93..d30eab098c 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/DataInputExtender.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/DataInputExtender.java @@ -130,6 +130,14 @@ public class DataInputExtender implements ExtendedDataInput return ExtendedIOUtil.readEnum(input, type); } + /** + * @since 3.4 + */ + public Throwable readException() throws IOException + { + return ExtendedIOUtil.readException(input); + } + public int skipBytes(int n) throws IOException { return input.skipBytes(n); diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/DataOutputExtender.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/DataOutputExtender.java index f2879e6d1d..dda9b73cf4 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/DataOutputExtender.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/DataOutputExtender.java @@ -117,4 +117,12 @@ public class DataOutputExtender implements ExtendedDataOutput { ExtendedIOUtil.writeEnum(output, literal); } + + /** + * @since 3.4 + */ + public void writeException(Throwable t) throws IOException + { + ExtendedIOUtil.writeException(output, t); + } } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataInput.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataInput.java index 2418d588d3..faa4263a49 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataInput.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataInput.java @@ -19,6 +19,8 @@ import java.io.InputStream; /** * @author Eike Stepper + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. */ public interface ExtendedDataInput extends DataInput { @@ -38,6 +40,11 @@ public interface ExtendedDataInput extends DataInput public <T extends Enum<?>> T readEnum(Class<T> type) throws IOException; /** + * @since 3.4 + */ + public Throwable readException() throws IOException; + + /** * @author Eike Stepper * @since 2.0 */ @@ -143,6 +150,14 @@ public interface ExtendedDataInput extends DataInput return delegate.readEnum(type); } + /** + * @since 3.4 + */ + public Throwable readException() throws IOException + { + return delegate.readException(); + } + public int readUnsignedByte() throws IOException { return delegate.readUnsignedByte(); diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataInputStream.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataInputStream.java index c2904e9593..b57de4d1bb 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataInputStream.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataInputStream.java @@ -49,6 +49,14 @@ public class ExtendedDataInputStream extends DataInputStream implements Extended return ExtendedIOUtil.readEnum(this, type); } + /** + * @since 3.4 + */ + public Throwable readException() throws IOException + { + return ExtendedIOUtil.readException(this); + } + public Object readObject(ClassLoader classLoader) throws IOException { return ExtendedIOUtil.readObject(this, classLoader); diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataOutput.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataOutput.java index a0e5b58158..29c32aa0ae 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataOutput.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataOutput.java @@ -16,6 +16,8 @@ import java.io.OutputStream; /** * @author Eike Stepper + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. */ public interface ExtendedDataOutput extends DataOutput { @@ -31,6 +33,11 @@ public interface ExtendedDataOutput extends DataOutput public void writeEnum(Enum<?> literal) throws IOException; /** + * @since 3.4 + */ + public void writeException(Throwable t) throws IOException; + + /** * @author Eike Stepper * @since 2.0 */ @@ -136,6 +143,14 @@ public interface ExtendedDataOutput extends DataOutput delegate.writeEnum(literal); } + /** + * @since 3.4 + */ + public void writeException(Throwable t) throws IOException + { + delegate.writeException(t); + } + public void writeUTF(String str) throws IOException { delegate.writeUTF(str); diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataOutputStream.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataOutputStream.java index f0089f8ef6..3f5a944415 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataOutputStream.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedDataOutputStream.java @@ -42,6 +42,14 @@ public class ExtendedDataOutputStream extends DataOutputStream implements Extend ExtendedIOUtil.writeEnum(this, literal); } + /** + * @since 3.4 + */ + public void writeException(Throwable t) throws IOException + { + ExtendedIOUtil.writeException(this, t); + } + public void writeObject(Object object) throws IOException { ExtendedIOUtil.writeObject(this, object); diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java index 60814014a7..dcd5ab01bc 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java @@ -11,11 +11,16 @@ package org.eclipse.net4j.util.io; import org.eclipse.net4j.internal.util.bundle.OM; +import org.eclipse.net4j.util.StringUtil; import org.eclipse.net4j.util.WrappedException; import org.eclipse.net4j.util.om.trace.ContextTracer; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.DataInput; +import java.io.DataInputStream; import java.io.DataOutput; +import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInput; @@ -359,6 +364,71 @@ public final class ExtendedIOUtil return literals[ordinal - Byte.MIN_VALUE - 1]; } + /** + * @since 3.4 + */ + public static void writeException(DataOutput out, Throwable t) throws IOException + { + String message = StringUtil.formatException(t); + writeString(out, message); + + byte[] bytes = ExtendedIOUtil.serializeThrowable(t); + writeByteArray(out, bytes); + } + + /** + * @since 3.4 + */ + public static Throwable readException(DataInput in) throws IOException + { + String message = readString(in); + byte[] bytes = readByteArray(in); + + try + { + return ExtendedIOUtil.deserializeThrowable(bytes); + } + catch (Throwable couldNotLoadExceptionClass) + { + return new RuntimeException(message); + } + } + + /** + * @since 3.4 + */ + public static byte[] serializeThrowable(Throwable t) + { + try + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + writeObject(dos, t); + return baos.toByteArray(); + } + catch (Exception ex) + { + return null; + } + } + + /** + * @since 3.4 + */ + public static Throwable deserializeThrowable(byte[] bytes) + { + try + { + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + DataInputStream dis = new DataInputStream(bais); + return (Throwable)readObject(dis, OM.class.getClassLoader()); + } + catch (IOException ex) + { + return null; + } + } + private static <T> T[] getEnumLiterals(Class<T> type) { T[] literals = type.getEnumConstants(); diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java index 7b2bd3a6cc..631c7a60a7 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java @@ -10,6 +10,7 @@ */ package org.eclipse.net4j.signal; + /** * An exception that wraps an exception that has been thrown during the execution of a remote {@link SignalReactor signal}. * diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionIndication.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionIndication.java index 21088387f6..501064b8e2 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionIndication.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionIndication.java @@ -16,10 +16,6 @@ import org.eclipse.net4j.util.om.trace.ContextTracer; import org.eclipse.internal.net4j.bundle.OM; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - /** * @author Eike Stepper */ @@ -48,7 +44,7 @@ class RemoteExceptionIndication extends Indication try { - t = deserializeThrowable(in.readByteArray()); + t = ExtendedIOUtil.deserializeThrowable(in.readByteArray()); } catch (Throwable couldNotLoadExceptionClass) { @@ -66,18 +62,4 @@ class RemoteExceptionIndication extends Indication protocol.handleRemoteException(correlationID, t, responding); } } - - public static Throwable deserializeThrowable(byte[] bytes) - { - try - { - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - DataInputStream dis = new DataInputStream(bais); - return (Throwable)ExtendedIOUtil.readObject(dis, OM.class.getClassLoader()); - } - catch (IOException ex) - { - return null; - } - } } diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionRequest.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionRequest.java index 08fdfccf2f..1632e10d5d 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionRequest.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionRequest.java @@ -16,15 +16,12 @@ import org.eclipse.net4j.util.om.trace.ContextTracer; import org.eclipse.internal.net4j.bundle.OM; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; - /** * @author Eike Stepper */ class RemoteExceptionRequest extends Request { - private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SIGNAL, RemoteExceptionRequest.class); + public static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SIGNAL, RemoteExceptionRequest.class); private int correlationID; @@ -56,25 +53,10 @@ class RemoteExceptionRequest extends Request out.writeInt(correlationID); out.writeBoolean(responding); out.writeString(message); - out.writeByteArray(serializeThrowable(t)); - } - - public static byte[] serializeThrowable(Throwable t) - { - try - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - ExtendedIOUtil.writeObject(dos, t); - return baos.toByteArray(); - } - catch (Exception ex) - { - return null; - } + out.writeByteArray(ExtendedIOUtil.serializeThrowable(t)); } - public static String getFirstLine(String message) + static String getFirstLine(String message) { if (message == null) { |