diff --git a/jps/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java b/jps/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java index da5842fa0f1..ef37d49ae46 100644 --- a/jps/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java +++ b/jps/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.jps.build; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.StreamUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; @@ -38,6 +39,7 @@ import org.jetbrains.jet.compiler.runner.SimpleOutputItem; import org.jetbrains.jet.config.IncrementalCompilation; import org.jetbrains.jet.jps.JpsKotlinCompilerSettings; import org.jetbrains.jet.jps.incremental.IncrementalCacheImpl; +import org.jetbrains.jet.preloading.ClassLoaderFactory; import org.jetbrains.jet.utils.PathUtil; import org.jetbrains.jps.ModuleChunk; import org.jetbrains.jps.builders.BuildTarget; @@ -53,8 +55,10 @@ import org.jetbrains.jps.model.module.JpsModule; import java.io.File; import java.io.FileFilter; import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.net.URL; import java.util.*; import static org.jetbrains.jet.cli.common.messages.CompilerMessageLocation.NO_LOCATION; @@ -114,7 +118,14 @@ public class KotlinBuilder extends ModuleLevelBuilder { File outputDir = representativeTarget.getOutputDir(); - CompilerEnvironment environment = CompilerEnvironment.getEnvironmentFor(PathUtil.getKotlinPathsForJpsPluginOrJpsTests(), outputDir); + CompilerEnvironment environment = CompilerEnvironment.getEnvironmentFor( + PathUtil.getKotlinPathsForJpsPluginOrJpsTests(), outputDir, new ClassLoaderFactory() { + @Override + public ClassLoader create(ClassLoader compilerClassLoader) { + return new MyClassLoader(compilerClassLoader); + } + } + ); if (!environment.success()) { if (!hasKotlinFiles(chunk)) { // Configuration is bad, but there's nothing to compile anyways @@ -374,4 +385,49 @@ public class KotlinBuilder extends ModuleLevelBuilder { public List getCompilableFileExtensions() { return COMPILABLE_FILE_EXTENSIONS; } + + private class MyClassLoader extends ClassLoader { + private final ClassLoader compilerClassLoader; + private final ClassLoader jpsPluginClassLoader = KotlinBuilder.this.getClass().getClassLoader(); + + private MyClassLoader(ClassLoader compilerClassLoader) { + this.compilerClassLoader = compilerClassLoader; + } + + @NotNull + @Override + public Enumeration getResources(String name) throws IOException { + return jpsPluginClassLoader.getResources(name); + } + + @Override + public Class loadClass(@NotNull String name) throws ClassNotFoundException { + if (name.startsWith("org.jetbrains.jet.jps.incremental.")) { + return loadClassFromBytes(name); + } + else if (name.startsWith("org.jetbrains.jet.lang.resolve.kotlin.incremental.")) { + return compilerClassLoader.loadClass(name); + } + else { + return jpsPluginClassLoader.loadClass(name); + } + } + + private Class loadClassFromBytes(String name) throws ClassNotFoundException { + String classResource = name.replace('.', '/') + ".class"; + InputStream resource = jpsPluginClassLoader.getResourceAsStream(classResource); + if (resource == null) { + return null; + } + byte[] bytes; + try { + bytes = StreamUtil.loadFromStream(resource); + } + catch (IOException e) { + throw new ClassNotFoundException("Couldn't load class " + name, e); + } + + return defineClass(name, bytes, 0, bytes.length); + } + } }