diff --git a/compiler/testData/codegen/classPathInParentClassLoader/kt2781.java b/compiler/testData/codegen/classPathInParentClassLoader/kt2781.java deleted file mode 100644 index 68924bb5134..00000000000 --- a/compiler/testData/codegen/classPathInParentClassLoader/kt2781.java +++ /dev/null @@ -1,9 +0,0 @@ -import java.lang.String; - -class J { - String value; - - J(String value) { - this.value = value; - } -} diff --git a/compiler/testData/codegen/classPathInParentClassLoader/kt2781.kt b/compiler/testData/codegen/classPathInParentClassLoader/kt2781.kt deleted file mode 100644 index d8ef488e060..00000000000 --- a/compiler/testData/codegen/classPathInParentClassLoader/kt2781.kt +++ /dev/null @@ -1 +0,0 @@ -fun doTest() = J("OK").value diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ClassPathInParentClassLoaderTest.java b/compiler/tests/org/jetbrains/kotlin/codegen/ClassPathInParentClassLoaderTest.java deleted file mode 100644 index e081698623a..00000000000 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ClassPathInParentClassLoaderTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * 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.jetbrains.kotlin.codegen; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles; -import org.jetbrains.kotlin.cli.jvm.compiler.JetCoreEnvironment; -import org.jetbrains.kotlin.test.ConfigurationKind; -import org.jetbrains.kotlin.test.JetTestUtils; -import org.jetbrains.kotlin.test.TestJdkKind; - -import java.io.File; -import java.net.URLClassLoader; - -import static org.jetbrains.kotlin.codegen.CodegenTestUtil.assertThrows; -import static org.jetbrains.kotlin.codegen.CodegenTestUtil.compileJava; - -public class ClassPathInParentClassLoaderTest extends CodegenTestCase { - @NotNull - @Override - protected GeneratedClassLoader createClassLoader(@NotNull ClassFileFactory factory) { - ClassLoader parentClassLoader = new URLClassLoader(getClassPathURLs(), null); - initializedClassLoader = new GeneratedClassLoader(factory, parentClassLoader); - return initializedClassLoader; - } - - public void testKt2781() throws Exception { - File javaClassesTempDirectory = compileJava("classPathInParentClassLoader/kt2781.java"); - - myEnvironment = JetCoreEnvironment.createForTests( - getTestRootDisposable(), - JetTestUtils.compilerConfigurationForTests(ConfigurationKind.JDK_ONLY, TestJdkKind.MOCK_JDK, - JetTestUtils.getAnnotationsJar(), javaClassesTempDirectory), - EnvironmentConfigFiles.JVM_CONFIG_FILES); - - loadFile("classPathInParentClassLoader/kt2781.kt"); - assertThrows(generateFunction(), IllegalAccessError.class, null); - } -} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java index 6d922c9e310..df20229d722 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java @@ -122,25 +122,19 @@ public abstract class CodegenTestCase extends UsefulTestCase { } @NotNull - protected GeneratedClassLoader createClassLoader(@NotNull ClassFileFactory factory) { + protected GeneratedClassLoader generateAndCreateClassLoader() { if (initializedClassLoader != null) { fail("Double initialization of class loader in same test"); } - initializedClassLoader = new GeneratedClassLoader(factory, null, getClassPathURLs()); - return initializedClassLoader; - } - - @NotNull - protected GeneratedClassLoader generateAndCreateClassLoader() { ClassFileFactory factory = generateClassesInFile(); - GeneratedClassLoader loader = createClassLoader(factory); + initializedClassLoader = new GeneratedClassLoader(factory, ForTestCompileRuntime.runtimeJarClassLoader(), getClassPathURLs()); - if (!verifyAllFilesWithAsm(factory, loader)) { + if (!verifyAllFilesWithAsm(factory, initializedClassLoader)) { fail("Verification failed: see exceptions above"); } - return loader; + return initializedClassLoader; } @NotNull @@ -149,17 +143,11 @@ public abstract class CodegenTestCase extends UsefulTestCase { for (File file : myEnvironment.getConfiguration().getList(JVMConfigurationKeys.CLASSPATH_KEY)) { try { urls.add(file.toURI().toURL()); - } catch (MalformedURLException e) { + } + catch (MalformedURLException e) { throw new RuntimeException(e); } } - try { - //add runtime library - urls.add(ForTestCompileRuntime.runtimeJarForTests().toURI().toURL()); - } - catch (MalformedURLException e) { - throw new RuntimeException(e); - } return urls.toArray(new URL[urls.size()]); } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/TestlibTest.java b/compiler/tests/org/jetbrains/kotlin/codegen/TestlibTest.java index 9055aaf1bcd..654405eb093 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/TestlibTest.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/TestlibTest.java @@ -21,6 +21,7 @@ import junit.extensions.TestSetup; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys; import org.jetbrains.kotlin.cli.common.messages.MessageCollectorPlainTextToStream; import org.jetbrains.kotlin.cli.jvm.JVMConfigurationKeys; @@ -45,8 +46,6 @@ import org.jetbrains.kotlin.types.JetType; import java.io.File; import java.lang.reflect.Modifier; -import java.net.URL; -import java.net.URLClassLoader; import static org.jetbrains.kotlin.types.TypeUtils.getAllSupertypes; @@ -102,11 +101,9 @@ public class TestlibTest extends UsefulTestCase { throw new RuntimeException("There were compilation errors"); } - classLoader = new GeneratedClassLoader(generationState.getFactory(), - new URLClassLoader(new URL[] {ForTestCompileRuntime.runtimeJarForTests().toURI().toURL()}, - null)) { + classLoader = new GeneratedClassLoader(generationState.getFactory(), ForTestCompileRuntime.runtimeJarClassLoader()) { @Override - public Class loadClass(String name) throws ClassNotFoundException { + public Class loadClass(@NotNull String name) throws ClassNotFoundException { if (name.startsWith("junit.") || name.startsWith("org.junit.")) { //In other way we don't find any test cause will have two different TestCase classes! return TestlibTest.class.getClassLoader().loadClass(name); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java b/compiler/tests/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java index 6865f851c77..c43665e5926 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java @@ -19,8 +19,16 @@ package org.jetbrains.kotlin.codegen.forTestCompile; import org.jetbrains.annotations.NotNull; import java.io.File; +import java.lang.ref.SoftReference; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +import static org.jetbrains.kotlin.utils.UtilsPackage.rethrow; public class ForTestCompileRuntime { + private static volatile SoftReference runtimeJarClassLoader = new SoftReference(null); + @NotNull public static File runtimeJarForTests() { File runtime = new File("dist/kotlinc/lib/kotlin-runtime.jar"); @@ -29,4 +37,20 @@ public class ForTestCompileRuntime { } return runtime; } + + @NotNull + public static synchronized ClassLoader runtimeJarClassLoader() { + ClassLoader loader = runtimeJarClassLoader.get(); + if (loader == null) { + try { + loader = new URLClassLoader(new URL[] {runtimeJarForTests().toURI().toURL()}, null); + } + catch (MalformedURLException e) { + throw rethrow(e); + } + runtimeJarClassLoader = new SoftReference(loader); + } + + return loader; + } } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractCompileKotlinAgainstKotlinTest.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractCompileKotlinAgainstKotlinTest.java index f014f47921b..1485ffb79bb 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractCompileKotlinAgainstKotlinTest.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractCompileKotlinAgainstKotlinTest.java @@ -105,26 +105,25 @@ public abstract class AbstractCompileKotlinAgainstKotlinTest extends TestCaseWit } private void invokeMain() throws Exception { - URLClassLoader classLoader = new URLClassLoader( - new URL[]{ aDir.toURI().toURL(), bDir.toURI().toURL(), ForTestCompileRuntime.runtimeJarForTests().toURI().toURL() }, - AbstractCompileKotlinAgainstKotlinTest.class.getClassLoader() - ); - Class clazz = classLoader.loadClass(PackageClassUtils.getPackageClassName(FqName.ROOT)); - Method main = clazz.getMethod("main", String[].class); + Method main = generatedClass().getMethod("main", String[].class); main.invoke(null, new Object[] {ArrayUtil.EMPTY_STRING_ARRAY}); } private void invokeBox() throws Exception { - URLClassLoader classLoader = new URLClassLoader( - new URL[]{ bDir.toURI().toURL(), aDir.toURI().toURL(), ForTestCompileRuntime.runtimeJarForTests().toURI().toURL() }, - AbstractCompileKotlinAgainstKotlinTest.class.getClassLoader() - ); - Class clazz = classLoader.loadClass(PackageClassUtils.getPackageClassName(FqName.ROOT)); - Method box = clazz.getMethod("box"); + Method box = generatedClass().getMethod("box"); String result = (String) box.invoke(null); assertEquals("OK", result); } + @NotNull + private Class generatedClass() throws Exception { + URLClassLoader classLoader = new URLClassLoader( + new URL[]{ bDir.toURI().toURL(), aDir.toURI().toURL() }, + ForTestCompileRuntime.runtimeJarClassLoader() + ); + return classLoader.loadClass(PackageClassUtils.getPackageClassName(FqName.ROOT)); + } + private OutputFileCollection compileA(@NotNull File ktAFile) throws IOException { JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(getTestRootDisposable(), ConfigurationKind.ALL); diff --git a/compiler/tests/org/jetbrains/kotlin/runtime/ProgressionUtilTest.java b/compiler/tests/org/jetbrains/kotlin/runtime/ProgressionUtilTest.java index dc261ca1f23..0dcb98a3d23 100644 --- a/compiler/tests/org/jetbrains/kotlin/runtime/ProgressionUtilTest.java +++ b/compiler/tests/org/jetbrains/kotlin/runtime/ProgressionUtilTest.java @@ -20,8 +20,6 @@ import com.intellij.testFramework.UsefulTestCase; import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime; import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; public class ProgressionUtilTest extends UsefulTestCase { private static final int MAX = Integer.MAX_VALUE; @@ -33,8 +31,7 @@ public class ProgressionUtilTest extends UsefulTestCase { @Override protected void setUp() throws Exception { super.setUp(); - ClassLoader classLoader = new URLClassLoader(new URL[] {ForTestCompileRuntime.runtimeJarForTests().toURI().toURL()}, null); - Class progressionUtil = classLoader.loadClass("kotlin.internal.InternalPackage"); + Class progressionUtil = ForTestCompileRuntime.runtimeJarClassLoader().loadClass("kotlin.internal.InternalPackage"); this.intMethod = progressionUtil.getMethod("getProgressionFinalElement", int.class, int.class, int.class); this.longMethod = progressionUtil.getMethod("getProgressionFinalElement", long.class, long.class, long.class); } diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/AbstractLocalClassProtoTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/AbstractLocalClassProtoTest.kt index c58543f4c30..87a78119163 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/AbstractLocalClassProtoTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/AbstractLocalClassProtoTest.kt @@ -16,31 +16,27 @@ package org.jetbrains.kotlin.serialization -import org.jetbrains.kotlin.jvm.compiler.LoadDescriptorUtil -import org.jetbrains.kotlin.test.TestCaseWithTmpdir -import java.io.File -import org.jetbrains.kotlin.test.ConfigurationKind -import java.net.URLClassLoader -import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime -import org.jetbrains.kotlin.test.JetTestUtils -import org.jetbrains.kotlin.cli.jvm.compiler.JetCoreEnvironment -import org.jetbrains.kotlin.test.TestJdkKind +import com.google.common.base.Predicates +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles -import org.jetbrains.kotlin.test.InTextDirectivesUtils +import org.jetbrains.kotlin.cli.jvm.compiler.JetCoreEnvironment +import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime +import org.jetbrains.kotlin.context.GlobalContext +import org.jetbrains.kotlin.di.InjectorForTopDownAnalyzerForJvm +import org.jetbrains.kotlin.jvm.compiler.LoadDescriptorUtil +import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.di.InjectorForTopDownAnalyzerForJvm -import com.intellij.psi.search.GlobalSearchScope -import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM -import org.jetbrains.kotlin.context.GlobalContext -import org.jetbrains.kotlin.resolve.TopDownAnalysisParameters -import com.google.common.base.Predicates -import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport -import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory -import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator import org.jetbrains.kotlin.name.FqNameUnsafe -import org.jetbrains.kotlin.load.java.JvmAnnotationNames +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.TopDownAnalysisParameters +import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM +import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory +import org.jetbrains.kotlin.test.* +import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator +import java.io.File +import java.net.URLClassLoader public abstract class AbstractLocalClassProtoTest : TestCaseWithTmpdir() { protected fun doTest(filename: String) { @@ -50,7 +46,7 @@ public abstract class AbstractLocalClassProtoTest : TestCaseWithTmpdir() { val classNameSuffix = InTextDirectivesUtils.findStringWithPrefixes(source.readText(), "// CLASS_NAME_SUFFIX: ") ?: error("CLASS_NAME_SUFFIX directive not found in test data") - val classLoader = URLClassLoader(array(tmpdir.toURI().toURL(), ForTestCompileRuntime.runtimeJarForTests().toURI().toURL()), null) + val classLoader = URLClassLoader(array(tmpdir.toURI().toURL()), ForTestCompileRuntime.runtimeJarClassLoader()) val classFile = tmpdir.listFiles().singleOrNull { it.getPath().endsWith("$classNameSuffix.class") } ?: error("Local class with suffix `$classNameSuffix` is not found in: ${tmpdir.listFiles().toList()}")