diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java index 06246414b8..4b84cbe7aa 100644 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java @@ -26,7 +26,6 @@ import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; import org.hibernate.jpa.boot.internal.PersistenceXmlParser; import org.hibernate.jpa.boot.spi.Bootstrap; import org.keycloak.connections.jpa.entityprovider.JpaEntityProvider; -import org.keycloak.utils.ProxyClassLoader; import org.keycloak.models.KeycloakSession; import jakarta.persistence.EntityManager; @@ -74,8 +73,7 @@ public class JpaUtils { // to find and load the extra provided entities. persistenceUnit.setTransactionType(txType); persistenceUnit.setValidationMode(ValidationMode.NONE.name()); - return Bootstrap.getEntityManagerFactoryBuilder(persistenceUnit, properties, - new ProxyClassLoader(providedEntities)).build(); + return Bootstrap.getEntityManagerFactoryBuilder(persistenceUnit, properties).build(); } } throw new RuntimeException("Persistence unit '" + unitName + "' not found"); @@ -83,7 +81,7 @@ public class JpaUtils { /** * Get a list of all provided entities by looping over all configured entity providers. - * + * * @param session the keycloak session * @return a list of all provided entities (can be an empty list) */ diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/QuarkusPlatform.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/QuarkusPlatform.java index 4ba7992a78..ebd121dc18 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/QuarkusPlatform.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/QuarkusPlatform.java @@ -24,7 +24,6 @@ import java.nio.file.Path; import java.util.concurrent.atomic.AtomicBoolean; import org.jboss.logging.Logger; -import org.keycloak.Config; import org.keycloak.platform.PlatformProvider; import org.keycloak.quarkus.runtime.Environment; @@ -103,9 +102,4 @@ public class QuarkusPlatform implements PlatformProvider { return tmpDir; } - @Override - public ClassLoader getScriptEngineClassLoader(Config.Scope scriptProviderConfig) { - // It is fine to return null assuming that nashorn and it's dependencies are included on the classpath (usually "providers" directory) - return null; - } } diff --git a/server-spi-private/src/main/java/org/keycloak/utils/ProxyClassLoader.java b/server-spi-private/src/main/java/org/keycloak/utils/ProxyClassLoader.java deleted file mode 100644 index abc0318502..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/utils/ProxyClassLoader.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2022 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.keycloak.utils; - -import java.io.IOException; -import java.net.URL; -import java.util.Arrays; -import java.util.Collection; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Set; - -/** - * @author Erik Mulder - * - * Classloader implementation to facilitate loading classes and resources from a collection of other classloaders. - * Effectively it forms a proxy to one or more other classloaders. - * - * The way it works: - * - Get list of classloaders, which will be used as "delegates" when loaded classes or resources. - * - Can be retrieved from provided classloaders or alternatively from the provided classes where the "delegate classloaders" will be determined from the classloaders of given classes - * - For each class or resource that is 'requested': - * - First try all provided classloaders and if we have a match, return that - * - If no match was found: proceed with 'normal' classloading in 'current classpath' scope - * - * In this particular context: only loadClass and getResource overrides are needed, since those - * are the methods that a classloading and resource loading process will need. - */ -public class ProxyClassLoader extends ClassLoader { - - private Set classloaders; - - /** - * Init classloader with the list of given delegates - * @param delegateClassLoaders - */ - public ProxyClassLoader(ClassLoader... delegateClassLoaders) { - if (delegateClassLoaders == null || delegateClassLoaders.length == 0) { - throw new IllegalStateException("At least one classloader to delegate must be provided"); - } - classloaders = new LinkedHashSet<>(); - classloaders.addAll(Arrays.asList(delegateClassLoaders)); - } - - /** - * Get all unique classloaders from the provided classes to be used as "Delegate classloaders" - * @param classes - */ - public ProxyClassLoader(Collection> classes) { - init(classes); - } - - private void init(Collection> classes) { - classloaders = new LinkedHashSet<>(); - for (Class clazz : classes) { - classloaders.add(clazz.getClassLoader()); - } - } - - @Override - public Class loadClass(String name) throws ClassNotFoundException { - for (ClassLoader classloader : classloaders) { - try { - return classloader.loadClass(name); - } catch (ClassNotFoundException e) { - // This particular class loader did not find the class. It's expected behavior that - // this can happen, so we'll just ignore the exception and let the next one try. - } - } - // We did not find the class in the proxy class loaders, so proceed with 'normal' behavior. - return super.loadClass(name); - } - - @Override - public URL getResource(String name) { - for (ClassLoader classloader : classloaders) { - URL resource = classloader.getResource(name); - if (resource != null) { - return resource; - } - // Resource == null means not found, so let the next one try. - } - // We could not get the resource from the proxy class loaders, so proceed with 'normal' behavior. - return super.getResource(name); - } - - @Override - public Enumeration getResources(String name) throws IOException { - final LinkedHashSet resourceUrls = new LinkedHashSet(); - - for (ClassLoader classloader : classloaders) { - Enumeration child = classloader.getResources(name); - - while (child.hasMoreElements()) { - resourceUrls.add(child.nextElement()); - } - } - - return new Enumeration() { - final Iterator resourceUrlIterator = resourceUrls.iterator(); - - public boolean hasMoreElements() { - return this.resourceUrlIterator.hasNext(); - } - - public URL nextElement() { - return (URL)this.resourceUrlIterator.next(); - } - }; - } - - @Override - public String toString() { - return "ProxyClassLoader: Delegates: " + classloaders; - } -} diff --git a/services/src/main/java/org/keycloak/platform/PlatformProvider.java b/services/src/main/java/org/keycloak/platform/PlatformProvider.java index f28b4789f7..d9ca4fd656 100644 --- a/services/src/main/java/org/keycloak/platform/PlatformProvider.java +++ b/services/src/main/java/org/keycloak/platform/PlatformProvider.java @@ -24,7 +24,7 @@ import org.keycloak.Config; public interface PlatformProvider { String name(); - + default void onStartup(Runnable runnable) { } @@ -41,17 +41,4 @@ public interface PlatformProvider { */ File getTmpDirectory(); - - /** - * Returns classloader to load script engine. Classloader should contain the implementation of {@link javax.script.ScriptEngineFactory} - * and it's definition inside META-INF/services of the jar file(s), which will be provided by this classloader. - * - * This method can return null and in that case, the default Keycloak services classloader will be used for load script engine. Note that java versions earlier than 15 always contain - * the "nashorn" script engine by default on the classpath (it is part of the Java platform itself) and hence for them it is always fine to return null (unless you want to override default engine) - * - * @param scriptProviderConfig Configuration scope of the "default" provider of "scripting" SPI. It can contain some config properties for the classloader (EG. file path) - * @return classloader or null - */ - ClassLoader getScriptEngineClassLoader(Config.Scope scriptProviderConfig); - } diff --git a/services/src/main/java/org/keycloak/scripting/DefaultScriptingProvider.java b/services/src/main/java/org/keycloak/scripting/DefaultScriptingProvider.java index dc42513673..a6620ed99e 100644 --- a/services/src/main/java/org/keycloak/scripting/DefaultScriptingProvider.java +++ b/services/src/main/java/org/keycloak/scripting/DefaultScriptingProvider.java @@ -27,7 +27,6 @@ import org.jboss.logging.Logger; import org.keycloak.models.ScriptModel; import org.keycloak.platform.Platform; import org.keycloak.services.ServicesLogger; -import org.keycloak.utils.ProxyClassLoader; /** * A {@link ScriptingProvider} that uses a {@link ScriptEngineManager} to evaluate scripts with a {@link ScriptEngine}. @@ -128,24 +127,6 @@ public class DefaultScriptingProvider implements ScriptingProvider { * Looks-up a {@link ScriptEngine} based on the MIME-type provided by the given {@link Script}. */ private ScriptEngine lookupScriptEngineFor(ScriptModel script) { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - try { - ClassLoader scriptClassLoader = Platform.getPlatform().getScriptEngineClassLoader(factory.getConfig()); - - // Also need to use classloader of keycloak services itself to be able to use keycloak classes in the scripts - if (scriptClassLoader != null) { - scriptClassLoader = new ProxyClassLoader(scriptClassLoader, DefaultScriptingProvider.class.getClassLoader()); - } else { - scriptClassLoader = DefaultScriptingProvider.class.getClassLoader(); - } - - logger.debugf("Using classloader %s to load script engine", scriptClassLoader); - - Thread.currentThread().setContextClassLoader(scriptClassLoader); - return new ScriptEngineManager().getEngineByMimeType(script.getMimeType()); - } - finally { - Thread.currentThread().setContextClassLoader(cl); - } + return new ScriptEngineManager().getEngineByMimeType(script.getMimeType()); } } diff --git a/testsuite/utils/src/main/java/org/keycloak/testsuite/TestPlatform.java b/testsuite/utils/src/main/java/org/keycloak/testsuite/TestPlatform.java index 76f097062e..446984c658 100644 --- a/testsuite/utils/src/main/java/org/keycloak/testsuite/TestPlatform.java +++ b/testsuite/utils/src/main/java/org/keycloak/testsuite/TestPlatform.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.nio.file.Files; import org.jboss.logging.Logger; -import org.keycloak.Config; import org.keycloak.common.Profile; import org.keycloak.common.profile.PropertiesFileProfileConfigResolver; import org.keycloak.common.profile.PropertiesProfileConfigResolver; @@ -87,9 +86,4 @@ public class TestPlatform implements PlatformProvider { return tmpDir; } - @Override - public ClassLoader getScriptEngineClassLoader(Config.Scope scriptProviderConfig) { - // It is fine to return null as nashorn should be automatically included on the classpath of testsuite utils - return null; - } }