| /* |
| * Copyright 2000-2012 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.jps.cmdline; |
| |
| import com.google.protobuf.Message; |
| import com.intellij.compiler.notNullVerification.NotNullVerifyingInstrumenter; |
| import com.intellij.openapi.application.PathManager; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.util.io.FileUtil; |
| import com.intellij.uiDesigner.compiler.AlienFormFileException; |
| import com.intellij.uiDesigner.core.GridConstraints; |
| import com.intellij.util.PathUtilRt; |
| import com.intellij.util.SystemProperties; |
| import com.intellij.util.containers.ContainerUtil; |
| import com.jgoodies.forms.layout.CellConstraints; |
| import io.netty.util.NetUtil; |
| import net.n3.nanoxml.IXMLBuilder; |
| import org.jetbrains.annotations.Nullable; |
| import org.jetbrains.asm4.ClassVisitor; |
| import org.jetbrains.asm4.ClassWriter; |
| import org.jetbrains.jps.builders.java.JavaSourceTransformer; |
| import org.jetbrains.jps.javac.JavacServer; |
| import org.jetbrains.jps.model.JpsModel; |
| import org.jetbrains.jps.model.impl.JpsModelImpl; |
| import org.jetbrains.jps.model.serialization.JpsProjectLoader; |
| |
| import javax.tools.*; |
| import java.io.File; |
| import java.util.*; |
| |
| /** |
| * @author Eugene Zhuravlev |
| * Date: 9/12/11 |
| */ |
| public class ClasspathBootstrap { |
| private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.cmdline.ClasspathBootstrap"); |
| |
| private static class OptimizedFileManagerClassHolder { |
| static final String CLASS_NAME = "org.jetbrains.jps.javac.OptimizedFileManager"; |
| @Nullable |
| static final Class<StandardJavaFileManager> managerClass; |
| @Nullable |
| static final String initError; |
| static { |
| Class<StandardJavaFileManager> aClass; |
| String error = null; |
| try { |
| @SuppressWarnings("unchecked") Class<StandardJavaFileManager> c = (Class<StandardJavaFileManager>)Class.forName(CLASS_NAME); |
| aClass = c; |
| } |
| catch (Throwable ex) { |
| aClass = null; |
| error = ex.getClass().getName() + ": " + ex.getMessage(); |
| } |
| managerClass = aClass; |
| initError = error; |
| } |
| |
| private OptimizedFileManagerClassHolder() { |
| } |
| } |
| |
| private static class OptimizedFileManager17ClassHolder { |
| static final String CLASS_NAME = "org.jetbrains.jps.javac.OptimizedFileManager17"; |
| @Nullable |
| static final Class<StandardJavaFileManager> managerClass; |
| @Nullable |
| static final String initError; |
| static { |
| Class<StandardJavaFileManager> aClass; |
| String error = null; |
| try { |
| @SuppressWarnings("unchecked") Class<StandardJavaFileManager> c = (Class<StandardJavaFileManager>)Class.forName(CLASS_NAME); |
| aClass = c; |
| } |
| catch (Throwable ex) { |
| aClass = null; |
| error = ex.getClass().getName() + ": " + ex.getMessage(); |
| } |
| managerClass = aClass; |
| initError = error; |
| } |
| |
| private OptimizedFileManager17ClassHolder() { |
| } |
| } |
| |
| private ClasspathBootstrap() { |
| } |
| |
| public static List<String> getBuildProcessApplicationClasspath(boolean isLauncherUsed) { |
| final Set<String> cp = ContainerUtil.newHashSet(); |
| |
| cp.add(getResourcePath(BuildMain.class)); |
| |
| cp.addAll(PathManager.getUtilClassPath()); // util |
| cp.add(getResourcePath(Message.class)); // protobuf |
| cp.add(getResourcePath(NetUtil.class)); // netty |
| cp.add(getResourcePath(ClassWriter.class)); // asm |
| cp.add(getResourcePath(ClassVisitor.class)); // asm-commons |
| cp.add(getResourcePath(JpsModel.class)); // jps-model-api |
| cp.add(getResourcePath(JpsModelImpl.class)); // jps-model-impl |
| cp.add(getResourcePath(JpsProjectLoader.class)); // jps-model-serialization |
| cp.add(getResourcePath(AlienFormFileException.class)); // forms-compiler |
| cp.add(getResourcePath(GridConstraints.class)); // forms-rt |
| cp.add(getResourcePath(CellConstraints.class)); // jGoodies-forms |
| cp.add(getResourcePath(NotNullVerifyingInstrumenter.class)); // not-null |
| cp.add(getResourcePath(IXMLBuilder.class)); // nano-xml |
| |
| if (!isLauncherUsed) { |
| appendJavaCompilerClasspath(cp); |
| } |
| |
| try { |
| final Class<?> cmdLineWrapper = Class.forName("com.intellij.rt.execution.CommandLineWrapper"); |
| cp.add(getResourcePath(cmdLineWrapper)); // idea_rt.jar |
| } |
| catch (Throwable ignored) { |
| } |
| |
| return ContainerUtil.newArrayList(cp); |
| } |
| |
| public static void appendJavaCompilerClasspath(Collection<String> cp) { |
| final Class<StandardJavaFileManager> optimizedFileManagerClass = getOptimizedFileManagerClass(); |
| if (optimizedFileManagerClass != null) { |
| cp.add(getResourcePath(optimizedFileManagerClass)); // optimizedFileManager |
| } |
| |
| for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) { // Eclipse compiler |
| final String compilerResource = getResourcePath(javaCompiler.getClass()); |
| final String name = PathUtilRt.getFileName(compilerResource); |
| if (name.startsWith("ecj-") && name.endsWith(".jar")) { |
| cp.add(compilerResource); |
| } |
| } |
| } |
| |
| public static List<File> getJavacServerClasspath(String sdkHome, boolean useEclipseCompiler) { |
| final Set<File> cp = new LinkedHashSet<File>(); |
| cp.add(getResourceFile(JavacServer.class)); // self |
| // util |
| for (String path : PathManager.getUtilClassPath()) { |
| cp.add(new File(path)); |
| } |
| cp.add(getResourceFile(JpsModel.class)); // jps-model-api |
| cp.add(getResourceFile(JpsModelImpl.class)); // jps-model-impl |
| cp.add(getResourceFile(Message.class)); // protobuf |
| cp.add(getResourceFile(NetUtil.class)); // netty |
| |
| final Class<StandardJavaFileManager> optimizedFileManagerClass = getOptimizedFileManagerClass(); |
| if (optimizedFileManagerClass != null) { |
| cp.add(getResourceFile(optimizedFileManagerClass)); // optimizedFileManager, if applicable |
| } |
| |
| try { |
| final Class<?> cmdLineWrapper = Class.forName("com.intellij.rt.execution.CommandLineWrapper"); |
| cp.add(getResourceFile(cmdLineWrapper)); // idea_rt.jar |
| } |
| catch (Throwable th) { |
| LOG.info(th); |
| } |
| |
| final JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); |
| if (systemCompiler != null) { |
| try { |
| final String localJarPath = FileUtil.toSystemIndependentName(getResourceFile(systemCompiler.getClass()).getPath()); |
| final String localJavaHome = FileUtil.toSystemIndependentName(SystemProperties.getJavaHome()); |
| if (FileUtil.pathsEqual(localJavaHome, FileUtil.toSystemIndependentName(sdkHome))) { |
| cp.add(new File(localJarPath)); |
| } |
| else { |
| // sdkHome is not the same as the sdk used to run this process |
| final File candidate = new File(sdkHome, "lib/tools.jar"); |
| if (candidate.exists()) { |
| cp.add(candidate); |
| } |
| else { |
| // last resort |
| String relPath = FileUtil.getRelativePath(localJavaHome, localJarPath, '/'); |
| if (relPath != null) { |
| if (relPath.contains("..")) { |
| relPath = FileUtil.getRelativePath(FileUtil.toSystemIndependentName(new File(localJavaHome).getParent()), localJarPath, '/'); |
| } |
| if (relPath != null) { |
| final File targetFile = new File(sdkHome, relPath); |
| cp.add(targetFile); // tools.jar |
| } |
| } |
| } |
| } |
| } |
| catch (Throwable th) { |
| LOG.info(th); |
| } |
| } |
| |
| if (useEclipseCompiler) { |
| // eclipse compiler |
| for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) { // Eclipse compiler |
| final File compilerResource = getResourceFile(javaCompiler.getClass()); |
| final String name = compilerResource.getName(); |
| if (name.startsWith("ecj-") && name.endsWith(".jar")) { |
| cp.add(compilerResource); |
| } |
| } |
| } |
| |
| final Class<JavaSourceTransformer> transformerClass = JavaSourceTransformer.class; |
| final ServiceLoader<JavaSourceTransformer> loader = ServiceLoader.load(transformerClass, transformerClass.getClassLoader()); |
| for (JavaSourceTransformer t : loader) { |
| cp.add(getResourceFile(t.getClass())); |
| } |
| |
| return new ArrayList<File>(cp); |
| } |
| |
| @Nullable |
| public static Class<StandardJavaFileManager> getOptimizedFileManagerClass() { |
| final Class<StandardJavaFileManager> aClass = OptimizedFileManagerClassHolder.managerClass; |
| if (aClass != null) { |
| return aClass; |
| } |
| return OptimizedFileManager17ClassHolder.managerClass; |
| } |
| |
| @Nullable |
| public static String getOptimizedFileManagerLoadError() { |
| StringBuilder builder = new StringBuilder(); |
| if (OptimizedFileManagerClassHolder.initError != null) { |
| builder.append(OptimizedFileManagerClassHolder.initError); |
| } |
| if (OptimizedFileManager17ClassHolder.initError != null) { |
| if (builder.length() > 0) { |
| builder.append("\n"); |
| } |
| builder.append(OptimizedFileManager17ClassHolder.initError); |
| } |
| return builder.toString(); |
| } |
| |
| public static String getResourcePath(Class aClass) { |
| return PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class"); |
| } |
| |
| public static File getResourceFile(Class aClass) { |
| return new File(getResourcePath(aClass)); |
| } |
| } |