IGNITE-2947: improving support of OSGi like environments at the level of binary marshalling
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1f99a917 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1f99a917 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1f99a917 Branch: refs/heads/ignite-3163 Commit: 1f99a917ec073206e9e2366da01830aa14d7d85a Parents: 2461d0d Author: Denis Magda <[email protected]> Authored: Sat May 7 00:21:22 2016 +0300 Committer: Denis Magda <[email protected]> Committed: Sat May 7 00:21:22 2016 +0300 ---------------------------------------------------------------------- .../internal/binary/BinaryClassDescriptor.java | 43 +++++++- .../ignite/internal/binary/BinaryContext.java | 101 +++++++++---------- .../internal/binary/BinaryReaderExImpl.java | 39 ++++--- .../binary/GridBinaryWildcardsSelfTest.java | 24 ++--- ...acheBinaryObjectUserClassloaderSelfTest.java | 38 ++++++- .../marshaller/MarshallerContextTestImpl.java | 7 ++ .../testframework/junits/GridAbstractTest.java | 3 +- 7 files changed, 166 insertions(+), 89 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/1f99a917/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java index 5e9d9c4..72de312 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java @@ -86,6 +86,9 @@ public class BinaryClassDescriptor { /** Configured serializer. */ private final BinarySerializer serializer; + /** Serializer that is passed during BinaryClassDescriptor construction. Can differ from {@link #serializer}. */ + private final BinarySerializer initialSerializer; + /** ID mapper. */ private final BinaryInternalMapper mapper; @@ -166,6 +169,8 @@ public class BinaryClassDescriptor { assert cls != null; assert mapper != null; + initialSerializer = serializer; + // If serializer is not defined at this point, then we have to user OptimizedMarshaller. useOptMarshaller = serializer == null; @@ -408,9 +413,45 @@ public class BinaryClassDescriptor { } /** + * @return Type name. + */ + String typeName() { + return typeName; + } + + /** + * @return Type mapper. + */ + BinaryInternalMapper mapper() { + return mapper; + } + + /** + * @return Serializer. + */ + BinarySerializer serializer() { + return serializer; + } + + /** + * @return Initial serializer that is passed during BinaryClassDescriptor construction. + * Can differ from {@link #serializer}. + */ + BinarySerializer initialSerializer() { + return initialSerializer; + } + + /** + * @return Affinity field key name. + */ + String affFieldKeyName() { + return affKeyFieldName; + } + + /** * @return User type flag. */ - public boolean userType() { + boolean userType() { return userType; } http://git-wip-us.apache.org/repos/asf/ignite/blob/1f99a917/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java index 0a1ed11..daf34ad 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java @@ -38,7 +38,6 @@ import java.util.LinkedList; import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -102,9 +101,6 @@ public class BinaryContext { /** System loader.*/ private static final ClassLoader sysLdr = U.gridClassLoader(); - /** Reference to class loader set in IgniteConfiguration.classLoader */ - private final ClassLoader cfgLdr; - /** */ private static final BinaryInternalMapper DFLT_MAPPER = new BinaryInternalMapper(new BinaryBasicNameMapper(false), new BinaryBasicIdMapper(true), false); @@ -157,10 +153,6 @@ public class BinaryContext { /** */ private final ConcurrentMap<Class<?>, BinaryClassDescriptor> descByCls = new ConcurrentHashMap8<>(); - /** Cached types for system and configuration class loader. */ - private final ConcurrentMap<ClassLoader, ConcurrentMap<Integer, BinaryClassDescriptor>> cachedTypes = - new ConcurrentHashMap8<>(); - /** */ private final Map<Integer, BinaryClassDescriptor> predefinedTypes = new HashMap<>(); @@ -218,7 +210,6 @@ public class BinaryContext { this.metaHnd = metaHnd; this.igniteCfg = igniteCfg; this.log = log; - this.cfgLdr = igniteCfg.getClassLoader(); colTypes.put(ArrayList.class, GridBinaryMarshaller.ARR_LIST); colTypes.put(LinkedList.class, GridBinaryMarshaller.LINKED_LIST); @@ -568,8 +559,13 @@ public class BinaryContext { BinaryClassDescriptor desc = descByCls.get(cls); - if (desc == null || !desc.registered()) + if (desc == null) desc = registerClassDescriptor(cls, deserialize); + else if (!desc.registered()) { + assert desc.userType(); + + desc = registerUserClassDescriptor(desc); + } return desc; } @@ -597,14 +593,6 @@ public class BinaryContext { if (ldr == null) ldr = sysLdr; - // Classes re-loading is unsupported for both system and configuration loaders. - if (userType && (ldr.equals(sysLdr) || ldr.equals(cfgLdr))) { - desc = descriptor(typeId, ldr); - - if (desc != null) - return desc; - } - Class cls; try { @@ -724,11 +712,6 @@ public class BinaryContext { new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, schemas, desc.isEnum()).wrap(this)); } - ClassLoader ldr = IgniteUtils.detectClassLoader(cls); - - if (ldr.equals(sysLdr) || ldr.equals(cfgLdr)) - cacheDescriptor(typeId, desc, ldr); - descByCls.put(cls, desc); typeId2Mapper.putIfAbsent(typeId, mapper); @@ -737,6 +720,47 @@ public class BinaryContext { } /** + * Creates and registers {@link BinaryClassDescriptor} for the given user {@code class}. + * + * @param desc Old descriptor that should be re-registered. + * @return Class descriptor. + */ + private BinaryClassDescriptor registerUserClassDescriptor(BinaryClassDescriptor desc) { + boolean registered; + + try { + registered = marshCtx.registerClass(desc.typeId(), desc.describedClass()); + } + catch (IgniteCheckedException e) { + throw new BinaryObjectException("Failed to register class.", e); + } + + if (registered) { + BinarySerializer serializer = desc.initialSerializer(); + + if (serializer == null) + serializer = serializerForClass(desc.describedClass()); + + desc = new BinaryClassDescriptor( + this, + desc.describedClass(), + true, + desc.typeId(), + desc.typeName(), + desc.affFieldKeyName(), + desc.mapper(), + serializer, + true, + true + ); + + descByCls.put(desc.describedClass(), desc); + } + + return desc; + } + + /** * Get serializer for class taking in count default one. * * @param cls Class. @@ -1039,17 +1063,12 @@ public class BinaryContext { mapper, serializer, true, - true /* registered */ + false ); fieldsMeta = desc.fieldsMeta(); schemas = desc.schema() != null ? Collections.singleton(desc.schema()) : null; - ClassLoader ldr = IgniteUtils.detectClassLoader(cls); - - if (ldr.equals(sysLdr) || ldr.equals(cfgLdr)) - cacheDescriptor(id, desc, ldr); - descByCls.put(cls, desc); } @@ -1173,30 +1192,6 @@ public class BinaryContext { return optmMarsh; } - private BinaryClassDescriptor descriptor(int typeId, ClassLoader ldr) { - ConcurrentMap<Integer, BinaryClassDescriptor> map = cachedTypes.get(ldr); - - if (map != null) - return map.get(typeId); - - return null; - } - - private void cacheDescriptor(int typeId, BinaryClassDescriptor dsc, ClassLoader ldr) { - ConcurrentMap<Integer, BinaryClassDescriptor> ldrMap = cachedTypes.get(ldr); - - if (ldrMap == null) { - ConcurrentMap<Integer, BinaryClassDescriptor> old = cachedTypes.putIfAbsent(ldr, - ldrMap = new ConcurrentHashMap<>()); - - if (old != null) - ldrMap = old; - } - - // Don't use putIfAbsent because descriptor's "registered" flag might has been changed. - ldrMap.put(typeId, dsc); - } - /** * Undeployment callback invoked when class loader is being undeployed. * http://git-wip-us.apache.org/repos/asf/ignite/blob/1f99a917/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java index f9e7aa5..9e7a1b3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java @@ -114,6 +114,9 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina /** Footer end. */ private final int footerLen; + /** Class descriptor. */ + private BinaryClassDescriptor desc; + /** Mapper. */ private final BinaryInternalMapper mapper; @@ -127,7 +130,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina private final int fieldIdLen; /** Offset size in bytes. */ - private final int fieldOffsetLen; + private final int fieldOffLen; /** Object schema. */ private final BinarySchema schema; @@ -202,7 +205,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina // Get trivial flag values. userType = BinaryUtils.isUserType(flags); fieldIdLen = BinaryUtils.fieldIdLength(flags); - fieldOffsetLen = BinaryUtils.fieldOffsetLength(flags); + fieldOffLen = BinaryUtils.fieldOffsetLength(flags); // Calculate footer borders and raw offset. if (BinaryUtils.hasSchema(flags)) { @@ -234,7 +237,9 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina int off = in.position(); // Registers class by type ID, at least locally if the cache is not ready yet. - typeId = ctx.descriptorForClass(BinaryUtils.doReadClass(in, ctx, ldr, typeId0), false).typeId(); + desc = ctx.descriptorForClass(BinaryUtils.doReadClass(in, ctx, ldr, typeId0), false); + + typeId = desc.typeId(); int clsNameLen = in.position() - off; @@ -259,7 +264,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina schemaId = 0; userType = false; fieldIdLen = 0; - fieldOffsetLen = 0; + fieldOffLen = 0; schema = null; } @@ -277,7 +282,10 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina * @return Descriptor. */ BinaryClassDescriptor descriptor() { - return ctx.descriptorForTypeId(userType, typeId, ldr, true); + if (desc == null) + desc = ctx.descriptorForTypeId(userType, typeId, ldr, true); + + return desc; } /** @@ -389,6 +397,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina return (T)obj; } + /** {@inheritDoc} */ @Override public byte readByte(String fieldName) throws BinaryObjectException { return findFieldByName(fieldName) && checkFlagNoHandles(BYTE) == Flag.NORMAL ? in.readByte() : 0; @@ -1439,7 +1448,8 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina break; case OBJ: - BinaryClassDescriptor desc = ctx.descriptorForTypeId(userType, typeId, ldr, true); + if (desc == null) + desc = ctx.descriptorForTypeId(userType, typeId, ldr, true); streamPosition(dataStart); @@ -1640,6 +1650,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina } /** + * @param fieldId Field ID. * @return Deserialized object. * @throws BinaryObjectException If failed. */ @@ -1717,7 +1728,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina builder.addField(fieldId); - searchPos += BinaryUtils.FIELD_ID_LEN + fieldOffsetLen; + searchPos += BinaryUtils.FIELD_ID_LEN + fieldOffLen; } return builder.build(); @@ -1799,8 +1810,8 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina } /** - * Try finding the field by ID. Used for types with stable schema (Serializable) to avoid - * (string -> ID) calculations. + * Try finding the field by ID. Used for types with stable schema (Serializable) to avoid (string -> ID) + * calculations. * * @param id Field ID. * @return {@code True} if field was found and stream was positioned accordingly. @@ -1851,9 +1862,9 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina */ private boolean trySetUserFieldPosition(int order) { if (order != BinarySchema.ORDER_NOT_FOUND) { - int offsetPos = footerStart + order * (fieldIdLen + fieldOffsetLen) + fieldIdLen; + int offsetPos = footerStart + order * (fieldIdLen + fieldOffLen) + fieldIdLen; - int pos = start + BinaryUtils.fieldOffsetRelative(in, offsetPos, fieldOffsetLen); + int pos = start + BinaryUtils.fieldOffsetRelative(in, offsetPos, fieldOffLen); streamPosition(pos); @@ -1884,14 +1895,14 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina if (id0 == id) { int pos = start + BinaryUtils.fieldOffsetRelative(in, searchPos + BinaryUtils.FIELD_ID_LEN, - fieldOffsetLen); + fieldOffLen); streamPosition(pos); return true; } - searchPos += BinaryUtils.FIELD_ID_LEN + fieldOffsetLen; + searchPos += BinaryUtils.FIELD_ID_LEN + fieldOffLen; } } @@ -2003,7 +2014,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina /** {@inheritDoc} */ @Override public long skip(long n) throws IOException { - return skipBytes((int) n); + return skipBytes((int)n); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/1f99a917/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryWildcardsSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryWildcardsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryWildcardsSelfTest.java index a424d13..f69cea4 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryWildcardsSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryWildcardsSelfTest.java @@ -85,9 +85,7 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<ClassLoader, ConcurrentMap<Integer, BinaryClassDescriptor>> ldrMap = U.field(ctx, "cachedTypes"); - - ConcurrentMap<Integer, BinaryClassDescriptor> types = ldrMap.get(U.gridClassLoader()); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); assertEquals(3, types.size()); @@ -160,9 +158,7 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<ClassLoader, ConcurrentMap<Integer, BinaryClassDescriptor>> ldrMap = U.field(ctx, "cachedTypes"); - - ConcurrentMap<Integer, BinaryClassDescriptor> types = ldrMap.get(U.gridClassLoader()); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); assertEquals(3, types.size()); @@ -351,9 +347,7 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<ClassLoader, ConcurrentMap<Integer, BinaryClassDescriptor>> ldrMap = U.field(ctx, "cachedTypes"); - - ConcurrentMap<Integer, BinaryClassDescriptor> types = ldrMap.get(U.gridClassLoader()); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); assertEquals(3, types.size()); @@ -394,9 +388,7 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<ClassLoader, ConcurrentMap<Integer, BinaryClassDescriptor>> ldrMap = U.field(ctx, "cachedTypes"); - - ConcurrentMap<Integer, BinaryClassDescriptor> types = ldrMap.get(U.gridClassLoader()); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); assertEquals(3, types.size()); @@ -469,9 +461,7 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<ClassLoader, ConcurrentMap<Integer, BinaryClassDescriptor>> ldrMap = U.field(ctx, "cachedTypes"); - - ConcurrentMap<Integer, BinaryClassDescriptor> types = ldrMap.get(U.gridClassLoader()); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); assertEquals(3, types.size()); @@ -591,9 +581,7 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<ClassLoader, ConcurrentMap<Integer, BinaryClassDescriptor>> ldrMap = U.field(ctx, "cachedTypes"); - - ConcurrentMap<Integer, BinaryClassDescriptor> types = ldrMap.get(U.gridClassLoader()); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); assertEquals(3, types.size()); http://git-wip-us.apache.org/repos/asf/ignite/blob/1f99a917/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectUserClassloaderSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectUserClassloaderSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectUserClassloaderSelfTest.java index 6dc2d71..4355796 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectUserClassloaderSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectUserClassloaderSelfTest.java @@ -51,6 +51,9 @@ public class GridCacheBinaryObjectUserClassloaderSelfTest extends GridCommonAbst private static volatile boolean deserialized = false; /** */ + private static volatile boolean useWrappingLoader = false; + + /** */ private TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); /** {@inheritDoc} */ @@ -74,7 +77,8 @@ public class GridCacheBinaryObjectUserClassloaderSelfTest extends GridCommonAbst cfg.setMarshaller(new BinaryMarshaller()); - cfg.setClassLoader(getExternalClassLoader()); + cfg.setClassLoader(useWrappingLoader ? new WrappingClassLoader(getExternalClassLoader()) : + getExternalClassLoader()); if (customBinaryConf) { BinarySerializer bs = new BinarySerializer() { @@ -132,10 +136,29 @@ public class GridCacheBinaryObjectUserClassloaderSelfTest extends GridCommonAbst return cacheCfg; } + /** * @throws Exception If test failed. */ public void testConfigurationRegistration() throws Exception { + useWrappingLoader = false; + + doTestConfigurationRegistration(); + } + + /** + * @throws Exception If test failed. + */ + public void testConfigurationRegistrationWithWrappingLoader() throws Exception { + useWrappingLoader = true; + + doTestConfigurationRegistration(); + } + + /** + * @throws Exception If test failed. + */ + private void doTestConfigurationRegistration() throws Exception { try { customBinaryConf = true; @@ -145,7 +168,9 @@ public class GridCacheBinaryObjectUserClassloaderSelfTest extends GridCommonAbst IgniteCache<Integer, Object> cache1 = i1.cache(null); IgniteCache<Integer, Object> cache2 = i2.cache(null); - ClassLoader ldr = i1.configuration().getClassLoader(); + ClassLoader ldr = useWrappingLoader ? + ((WrappingClassLoader)i1.configuration().getClassLoader()).getParent() : + i1.configuration().getClassLoader(); Object v1 = ldr.loadClass("org.apache.ignite.tests.p2p.CacheDeploymentTestValue").newInstance(); Object v2 = ldr.loadClass("org.apache.ignite.tests.p2p.CacheDeploymentTestValue2").newInstance(); @@ -237,4 +262,13 @@ public class GridCacheBinaryObjectUserClassloaderSelfTest extends GridCommonAbst return S.toString(TestValue2.class, this); } } + + /** + * + */ + private static class WrappingClassLoader extends ClassLoader { + public WrappingClassLoader(ClassLoader parent) { + super(parent); + } + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/1f99a917/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java index e4921f4..c600ca4 100644 --- a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java +++ b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java @@ -62,4 +62,11 @@ public class MarshallerContextTestImpl extends MarshallerContextAdapter { @Override protected String className(int id) { return map.get(id); } + + /** + * @return Internal map. + */ + public ConcurrentMap<Integer, String> internalMap() { + return map; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/1f99a917/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java index 27511ff..5be6fb9 100644 --- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java @@ -476,7 +476,8 @@ public abstract class GridAbstractTest extends TestCase { * @throws Exception If failed. {@link #afterTestsStopped()} will be called in this case. */ protected void beforeTestsStarted() throws Exception { - // No-op. + // Will clean and re-create marshaller directory from scratch. + U.resolveWorkDirectory("marshaller", true); } /**
