Reuse class loader for kotlin-runtime.jar in codegen tests

Also delete questionable ClassPathInParentClassLoaderTest
This commit is contained in:
Alexander Udalov
2015-02-25 14:23:21 +03:00
parent b99b1883bc
commit 6f0ccbfab8
9 changed files with 63 additions and 125 deletions
@@ -1,9 +0,0 @@
import java.lang.String;
class J {
String value;
J(String value) {
this.value = value;
}
}
@@ -1 +0,0 @@
fun doTest() = J("OK").value
@@ -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);
}
}
@@ -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()]);
}
@@ -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);
@@ -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<ClassLoader> runtimeJarClassLoader = new SoftReference<ClassLoader>(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<ClassLoader>(loader);
}
return loader;
}
}
@@ -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);
@@ -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);
}
@@ -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()}")