From 97f90cb2c7865665e6f152bec1f82f4ad784b389 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 20 Aug 2018 18:11:28 +0200 Subject: [PATCH] Cache reflection operations in AbstractSchemaAwareTest The design of AbstractSchemaAwareTest requires reflection-based loading of SchemaContext for each test case, which is slow. Instantiate weak caches to speed up tests which are co-located on the same class loader. Change-Id: I1a79d7e99f6efcccab37445f3de25a74cb6f02b6 Signed-off-by: Robert Varga --- .../impl/test/Bug1125RegressionTest.java | 4 +-- .../test/Bug1333DataChangeListenerTest.java | 3 +- .../impl/test/Bug1418AugmentationTest.java | 3 +- .../Bug2562DeserializedUnkeyedListTest.java | 4 +-- .../impl/test/Bug3090MultiKeyList.java | 4 +-- .../impl/test/DataTreeChangeListenerTest.java | 4 +-- .../ForwardedNotificationAdapterTest.java | 3 +- .../ListInsertionDataChangeListenerTest.java | 5 +-- .../binding/test/AbstractSchemaAwareTest.java | 33 +++++++++++++++---- .../ConstantSchemaAbstractDataBrokerTest.java | 3 ++ .../binding/test/SchemaContextSingleton.java | 4 ++- .../WildcardedDataChangeListenerTest.java | 3 +- ...eteNestedAugmentationListenParentTest.java | 4 +-- .../bugfix/WriteParentListenAugmentTest.java | 3 +- 14 files changed, 55 insertions(+), 25 deletions(-) diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java index 1348af1e72..cf278bd8ab 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java @@ -5,7 +5,6 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.controller.md.sal.binding.impl.test; import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_FOO_KEY; @@ -13,6 +12,7 @@ import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUti import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList; import com.google.common.collect.ImmutableSet; +import java.util.Set; import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.binding.test.AbstractDataTreeChangeListenerTest; @@ -46,7 +46,7 @@ public class Bug1125RegressionTest extends AbstractDataTreeChangeListenerTest { TreeComplexUsesAugment.class); @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class), BindingReflections.getModuleInfo(TreeComplexUsesAugment.class)); } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1333DataChangeListenerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1333DataChangeListenerTest.java index 90156f1fd8..1665bef48b 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1333DataChangeListenerTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1333DataChangeListenerTest.java @@ -17,6 +17,7 @@ import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUti import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList; import com.google.common.collect.ImmutableSet; +import java.util.Set; import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.binding.test.AbstractDataTreeChangeListenerTest; @@ -44,7 +45,7 @@ public class Bug1333DataChangeListenerTest extends AbstractDataTreeChangeListene TOP_PATH.child(TopLevelList.class).augmentation(TreeComplexUsesAugment.class); @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class), BindingReflections.getModuleInfo(TreeComplexUsesAugment.class)); } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java index 7c114e7ef9..f10674226e 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java @@ -17,6 +17,7 @@ import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUti import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList; import com.google.common.collect.ImmutableSet; +import java.util.Set; import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.binding.test.AbstractDataTreeChangeListenerTest; @@ -43,7 +44,7 @@ public class Bug1418AugmentationTest extends AbstractDataTreeChangeListenerTest new ListViaUsesKey("list key modified"); @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class), BindingReflections.getModuleInfo(TreeComplexUsesAugment.class), BindingReflections.getModuleInfo(TreeLeafOnlyUsesAugment.class)); diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug2562DeserializedUnkeyedListTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug2562DeserializedUnkeyedListTest.java index 70b43073b2..bb3fbc2448 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug2562DeserializedUnkeyedListTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug2562DeserializedUnkeyedListTest.java @@ -5,11 +5,11 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.controller.md.sal.binding.impl.test; import com.google.common.collect.ImmutableSet; import java.util.Arrays; +import java.util.Set; import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.binding.test.AbstractDataTreeChangeListenerTest; @@ -29,7 +29,7 @@ public class Bug2562DeserializedUnkeyedListTest extends AbstractDataTreeChangeLi private static final InstanceIdentifier ROOT_PATH = InstanceIdentifier.create(Root.class); @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of(BindingReflections.getModuleInfo(Root.class)); } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug3090MultiKeyList.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug3090MultiKeyList.java index a150d2432c..bf6f1b288d 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug3090MultiKeyList.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug3090MultiKeyList.java @@ -32,7 +32,7 @@ public class Bug3090MultiKeyList extends AbstractDataTreeChangeListenerTest { private static final InstanceIdentifier ROOT_PATH = InstanceIdentifier.create(Root.class); @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of(BindingReflections.getModuleInfo(Root.class)); } @@ -61,7 +61,7 @@ public class Bug3090MultiKeyList extends AbstractDataTreeChangeListenerTest { listener.verify(); } - private boolean checkData(Root expected, Root actual) { + private static boolean checkData(final Root expected, final Root actual) { if (actual == null) { return false; } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/DataTreeChangeListenerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/DataTreeChangeListenerTest.java index 58176a073c..91d86c1d59 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/DataTreeChangeListenerTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/DataTreeChangeListenerTest.java @@ -5,7 +5,6 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.controller.md.sal.binding.impl.test; import static org.junit.Assert.assertEquals; @@ -27,6 +26,7 @@ import com.google.common.collect.Iterables; import com.google.common.util.concurrent.SettableFuture; import java.util.ArrayList; import java.util.Collection; +import java.util.Set; import java.util.concurrent.TimeUnit; import org.junit.Before; import org.junit.Test; @@ -88,7 +88,7 @@ public class DataTreeChangeListenerTest extends AbstractConcurrentDataBrokerTest } @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of( BindingReflections.getModuleInfo(TwoLevelList.class), BindingReflections.getModuleInfo(TreeComplexUsesAugment.class) diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ForwardedNotificationAdapterTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ForwardedNotificationAdapterTest.java index 7c65043156..7eef5db450 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ForwardedNotificationAdapterTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ForwardedNotificationAdapterTest.java @@ -15,6 +15,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -39,7 +40,7 @@ public class ForwardedNotificationAdapterTest extends AbstractNotificationBroker private static final Logger LOG = LoggerFactory.getLogger(ForwardedNotificationAdapterTest.class); @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of(BindingReflections.getModuleInfo(TwoLevelListChanged.class)); } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java index 01e5e0e0c3..143cb8e1cb 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java @@ -45,7 +45,7 @@ public class ListInsertionDataChangeListenerTest extends AbstractDataTreeChangeL private static final InstanceIdentifier TOP_BAR = TOP.child(TopLevelList.class, TOP_BAR_KEY); @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class)); } @@ -160,7 +160,8 @@ public class ListInsertionDataChangeListenerTest extends AbstractDataTreeChangeL barListener.verify(); } - private Function, Boolean> topSubtreeModified(TopLevelList topFoo, TopLevelList topBar) { + private Function, Boolean> topSubtreeModified(final TopLevelList topFoo, + final TopLevelList topBar) { return match(ModificationType.SUBTREE_MODIFIED, TOP, (Function) dataBefore -> Objects.equals(top(topFoo), dataBefore), dataAfter -> { diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java index aebe05dd03..db77bc5799 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java @@ -7,23 +7,42 @@ */ package org.opendaylight.controller.md.sal.binding.test; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableSet; +import java.util.Set; import org.junit.Before; import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext; import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; import org.opendaylight.yangtools.yang.binding.YangModuleInfo; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -public abstract class AbstractSchemaAwareTest { +public abstract class AbstractSchemaAwareTest { + private static final LoadingCache> MODULE_INFO_CACHE = CacheBuilder.newBuilder() + .weakKeys().weakValues().build(new CacheLoader>() { + @Override + public Set load(final ClassLoader key) { + return BindingReflections.loadModuleInfos(key); + } + }); + private static final LoadingCache, SchemaContext> SCHEMA_CONTEXT_CACHE = + CacheBuilder.newBuilder().weakValues().build(new CacheLoader, SchemaContext>() { + @Override + public SchemaContext load(final Set key) { + final ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create(); + moduleContext.addModuleInfos(key); + return moduleContext.tryToCreateSchemaContext().get(); + } + }); - protected Iterable getModuleInfos() throws Exception { - return BindingReflections.loadModuleInfos(); + protected Set getModuleInfos() throws Exception { + return MODULE_INFO_CACHE.getUnchecked(Thread.currentThread().getContextClassLoader()); } protected SchemaContext getSchemaContext() throws Exception { - final Iterable moduleInfos = getModuleInfos(); - final ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create(); - moduleContext.addModuleInfos(moduleInfos); - return moduleContext.tryToCreateSchemaContext().get(); + // ImmutableSet guarantees non-null + return SCHEMA_CONTEXT_CACHE.getUnchecked(ImmutableSet.copyOf(getModuleInfos())); } @Before diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConstantSchemaAbstractDataBrokerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConstantSchemaAbstractDataBrokerTest.java index 7e245a3b15..93f15b70e9 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConstantSchemaAbstractDataBrokerTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConstantSchemaAbstractDataBrokerTest.java @@ -15,7 +15,10 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; * it for each Test, and is thus faster. * * @author Michael Vorburger + * @deprecated This class is no longer useful, as {@link AbstractSchemaAwareTest#getSchemaContext()} provides effective + * caching. */ +@Deprecated public class ConstantSchemaAbstractDataBrokerTest extends AbstractConcurrentDataBrokerTest { public ConstantSchemaAbstractDataBrokerTest() { diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/SchemaContextSingleton.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/SchemaContextSingleton.java index 49eb5aaf5c..32f84a8508 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/SchemaContextSingleton.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/SchemaContextSingleton.java @@ -17,12 +17,14 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; * SchemaContext. * * @author Michael Vorburger + * @deprecated This class should not be used, as it pollutes the classpath. */ +@Deprecated public final class SchemaContextSingleton { private static SchemaContext staticSchemaContext; - public static synchronized SchemaContext getSchemaContext(Supplier supplier) throws Exception { + public static synchronized SchemaContext getSchemaContext(final Supplier supplier) throws Exception { if (staticSchemaContext == null) { staticSchemaContext = supplier.get(); } diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/WildcardedDataChangeListenerTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/WildcardedDataChangeListenerTest.java index ff6d02bb9a..4f11c50e53 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/WildcardedDataChangeListenerTest.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/WildcardedDataChangeListenerTest.java @@ -13,6 +13,7 @@ import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastor import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.Uninterruptibles; import java.util.Collections; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -80,7 +81,7 @@ public class WildcardedDataChangeListenerTest extends AbstractDataTreeChangeList .withKey(LIST_VIA_USES_KEY).setName("john").build(); @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class), BindingReflections.getModuleInfo(TreeComplexUsesAugment.class)); } diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DeleteNestedAugmentationListenParentTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DeleteNestedAugmentationListenParentTest.java index d91267454a..81d7e9dc61 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DeleteNestedAugmentationListenParentTest.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DeleteNestedAugmentationListenParentTest.java @@ -5,10 +5,10 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.controller.sal.binding.test.bugfix; import com.google.common.collect.ImmutableSet; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -52,7 +52,7 @@ public class DeleteNestedAugmentationListenParentTest extends AbstractDataTreeCh .build(); @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class), BindingReflections.getModuleInfo(List11SimpleAugment.class)); } diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/WriteParentListenAugmentTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/WriteParentListenAugmentTest.java index d05e0b64ff..09836147f2 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/WriteParentListenAugmentTest.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/WriteParentListenAugmentTest.java @@ -11,6 +11,7 @@ import static org.junit.Assert.assertEquals; import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL; import com.google.common.collect.ImmutableSet; +import java.util.Set; import java.util.concurrent.TimeUnit; import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.DataBroker; @@ -42,7 +43,7 @@ public class WriteParentListenAugmentTest extends AbstractDataTreeChangeListener .builder(Top.class).child(TopLevelList.class, TLL_KEY).augmentation(TreeComplexUsesAugment.class).build(); @Override - protected Iterable getModuleInfos() throws Exception { + protected Set getModuleInfos() throws Exception { return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class), BindingReflections.getModuleInfo(TreeComplexUsesAugment.class)); } -- 2.36.6