diff --git a/bonita-integration-tests/bonita-integration-tests-client/src/main/java/org/bonitasoft/engine/CommonAPIIT.java b/bonita-integration-tests/bonita-integration-tests-client/src/main/java/org/bonitasoft/engine/CommonAPIIT.java index af2866c247..3889728075 100644 --- a/bonita-integration-tests/bonita-integration-tests-client/src/main/java/org/bonitasoft/engine/CommonAPIIT.java +++ b/bonita-integration-tests/bonita-integration-tests-client/src/main/java/org/bonitasoft/engine/CommonAPIIT.java @@ -23,6 +23,7 @@ import org.apache.commons.io.IOUtils; import org.assertj.core.api.Assertions; +import org.bonitasoft.engine.api.TenantAdministrationAPI; import org.bonitasoft.engine.bpm.bar.BarResource; import org.bonitasoft.engine.bpm.process.ProcessDefinition; import org.bonitasoft.engine.bpm.process.impl.ProcessDefinitionBuilder; @@ -37,6 +38,7 @@ import org.bonitasoft.engine.io.IOUtil; import org.bonitasoft.engine.search.SearchOptionsBuilder; import org.bonitasoft.engine.search.SearchResult; +import org.bonitasoft.engine.tenant.TenantResource; import org.bonitasoft.engine.test.APITestUtil; import org.bonitasoft.engine.test.junit.BonitaEngineRule; import org.junit.Rule; @@ -74,9 +76,24 @@ private void clean() throws BonitaException { cleanRoles(); cleanSupervisors(); checkThereAreNoWaitingEventsLeft(); + cleanBdm(); logoutOnTenant(); } + private void cleanBdm() throws BonitaException { + TenantAdministrationAPI tenantAdministrationAPI = getTenantAdministrationAPI(); + if (tenantAdministrationAPI.getBusinessDataModelResource() != TenantResource.NONE) { + if (!tenantAdministrationAPI.isPaused()) { + tenantAdministrationAPI.pause(); + } + try { + tenantAdministrationAPI.cleanAndUninstallBusinessDataModel(); + } finally { + tenantAdministrationAPI.resume(); + } + } + } + private void checkThereAreNoWaitingEventsLeft() throws BonitaException { SearchResult searchResult = (SearchResult) getCommandAPI() .execute("searchWaitingEventsCommand", diff --git a/bonita-integration-tests/bonita-integration-tests-local/src/test/java/org/bonitasoft/engine/application/installer/ApplicationInstallerUpdateIT.java b/bonita-integration-tests/bonita-integration-tests-local/src/test/java/org/bonitasoft/engine/application/installer/ApplicationInstallerUpdateIT.java index 770cba2e38..8d4efc7473 100644 --- a/bonita-integration-tests/bonita-integration-tests-local/src/test/java/org/bonitasoft/engine/application/installer/ApplicationInstallerUpdateIT.java +++ b/bonita-integration-tests/bonita-integration-tests-local/src/test/java/org/bonitasoft/engine/application/installer/ApplicationInstallerUpdateIT.java @@ -51,7 +51,6 @@ import org.bonitasoft.engine.search.SearchOptionsBuilder; import org.bonitasoft.engine.service.ServiceAccessorSingleton; import org.bonitasoft.engine.tenant.TenantResource; -import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -78,16 +77,6 @@ public void before() throws Exception { initFirstInstall(); } - @After - public void after() throws Exception { - if (!getTenantAdministrationAPI().isPaused()) { - getTenantAdministrationAPI().pause(); - getTenantAdministrationAPI().cleanAndUninstallBusinessDataModel(); - getTenantAdministrationAPI().resume(); - } - logoutOnTenant(); - } - private void initFirstInstall() throws Exception { // ensure application did not exist initially: assertThatExceptionOfType(ApplicationNotFoundException.class) diff --git a/bonita-integration-tests/bonita-test-utils/src/main/java/org/bonitasoft/engine/test/APITestUtil.java b/bonita-integration-tests/bonita-test-utils/src/main/java/org/bonitasoft/engine/test/APITestUtil.java index dcdde98dfa..e78c5dc3c8 100644 --- a/bonita-integration-tests/bonita-test-utils/src/main/java/org/bonitasoft/engine/test/APITestUtil.java +++ b/bonita-integration-tests/bonita-test-utils/src/main/java/org/bonitasoft/engine/test/APITestUtil.java @@ -211,6 +211,9 @@ public class APITestUtil extends PlatformTestUtil { public void clearSynchroRepository() { try { loginOnDefaultTenantWithDefaultTechnicalUser(); + if (getTenantAdministrationAPI().isPaused()) { + getTenantAdministrationAPI().resume(); + } ClientEventUtil.clearRepo(getCommandAPI()); logoutOnTenant(); } catch (final Exception e) { diff --git a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/ServerAPIImpl.java b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/ServerAPIImpl.java index ffb2814c12..65690f21e3 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/ServerAPIImpl.java +++ b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/ServerAPIImpl.java @@ -23,6 +23,7 @@ import java.text.MessageFormat; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; @@ -34,6 +35,7 @@ import org.bonitasoft.engine.api.impl.transaction.CustomTransactions; import org.bonitasoft.engine.api.internal.ServerAPI; import org.bonitasoft.engine.api.internal.ServerWrappedException; +import org.bonitasoft.engine.classloader.BonitaClassLoader; import org.bonitasoft.engine.classloader.ClassLoaderIdentifier; import org.bonitasoft.engine.classloader.ClassLoaderService; import org.bonitasoft.engine.classloader.SClassLoaderException; @@ -42,7 +44,13 @@ import org.bonitasoft.engine.core.login.LoginService; import org.bonitasoft.engine.core.platform.login.PlatformLoginService; import org.bonitasoft.engine.dependency.model.ScopeType; -import org.bonitasoft.engine.exception.*; +import org.bonitasoft.engine.exception.BonitaContextException; +import org.bonitasoft.engine.exception.BonitaException; +import org.bonitasoft.engine.exception.BonitaHomeConfigurationException; +import org.bonitasoft.engine.exception.BonitaHomeNotSetException; +import org.bonitasoft.engine.exception.BonitaRuntimeException; +import org.bonitasoft.engine.exception.TenantStatusException; +import org.bonitasoft.engine.exception.UnavailableLockException; import org.bonitasoft.engine.lock.BonitaLock; import org.bonitasoft.engine.lock.LockService; import org.bonitasoft.engine.maintenance.MaintenanceDetails; @@ -56,7 +64,11 @@ import org.bonitasoft.engine.service.APIAccessResolver; import org.bonitasoft.engine.service.ServiceAccessor; import org.bonitasoft.engine.service.impl.ServiceAccessorFactory; -import org.bonitasoft.engine.session.*; +import org.bonitasoft.engine.session.APISession; +import org.bonitasoft.engine.session.InvalidSessionException; +import org.bonitasoft.engine.session.PlatformSession; +import org.bonitasoft.engine.session.Session; +import org.bonitasoft.engine.session.SessionService; import org.bonitasoft.engine.sessionaccessor.SessionAccessor; import org.bonitasoft.engine.transaction.UserTransactionService; import org.slf4j.Logger; @@ -136,25 +148,35 @@ public Object invokeMethod(final Map options, final String } } catch (final BonitaRuntimeException | BonitaException bre) { fillGlobalContextForException(session, bre); - // reset class loader - Thread.currentThread().setContextClassLoader(baseClassLoader); throw createServerWrappedException(bre); } catch (final UndeclaredThrowableException ute) { - // reset class loader - Thread.currentThread().setContextClassLoader(baseClassLoader); throw createServerWrappedException(ute); } catch (final Throwable cause) { final BonitaRuntimeException throwableToWrap = wrapThrowable(cause); fillGlobalContextForException(session, throwableToWrap); - // reset class loader - Thread.currentThread().setContextClassLoader(baseClassLoader); throw createServerWrappedException(throwableToWrap); } finally { cleanSessionIfNeeded(sessionAccessor); + // Reset the original classloader when not an equivalent BonitaClassLoader + // We do not reset the the classloader if the original classloader and the current classloader are BonitaClassloader having the same name + // e.g. for the cleanAndUninstallBusinessDataModel API method that reset the current classloader + if (shouldResetClassloader(baseClassLoader, Thread.currentThread().getContextClassLoader())) { + Thread.currentThread().setContextClassLoader(baseClassLoader); + } logger.trace("End Server API call {} {}", apiInterfaceName, methodName); } } + private boolean shouldResetClassloader(ClassLoader baseClassLoader, ClassLoader currentClassloader) { + if (currentClassloader instanceof BonitaClassLoader bonitaClassLoader + && baseClassLoader instanceof BonitaClassLoader bonitaBaseClassLoader) { + // Classloader name is different, reset it + return !Objects.equals(bonitaClassLoader.getName(), bonitaBaseClassLoader.getName()); + } else { + return true; + } + } + protected BonitaRuntimeException wrapThrowable(final Throwable cause) { return new BonitaRuntimeException(cause); }