Beispiel #1
0
  void test(String[] opts, String className) throws Exception {
    count++;
    System.err.println("Test " + count + " " + Arrays.asList(opts) + " " + className);
    Path testSrcDir = Paths.get(System.getProperty("test.src"));
    Path testClassesDir = Paths.get(System.getProperty("test.classes"));
    Path classes = Paths.get("classes." + count);
    classes.createDirectory();

    Context ctx = new Context();
    PathFileManager fm = new JavacPathFileManager(ctx, true, null);
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    List<String> options = new ArrayList<String>();
    options.addAll(Arrays.asList(opts));
    options.addAll(Arrays.asList("-verbose", "-XDverboseCompilePolicy", "-d", classes.toString()));
    Iterable<? extends JavaFileObject> compilationUnits =
        fm.getJavaFileObjects(testSrcDir.resolve(className + ".java"));
    StringWriter sw = new StringWriter();
    PrintWriter out = new PrintWriter(sw);
    JavaCompiler.CompilationTask t =
        compiler.getTask(out, fm, null, options, null, compilationUnits);
    boolean ok = t.call();
    System.err.println(sw.toString());
    if (!ok) {
      throw new Exception("compilation failed");
    }

    File expect = new File("classes." + count + "/" + className + ".class");
    if (!expect.exists()) throw new Exception("expected file not found: " + expect);
    long expectedSize = new File(testClassesDir.toString(), className + ".class").length();
    long actualSize = expect.length();
    if (expectedSize != actualSize)
      throw new Exception("wrong size found: " + actualSize + "; expected: " + expectedSize);
  }
Beispiel #2
0
  public static void compileJavaFiles(
      @NotNull Collection<File> files, List<String> options, @Nullable File javaErrorFile)
      throws IOException {
    JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
    DiagnosticCollector<JavaFileObject> diagnosticCollector =
        new DiagnosticCollector<JavaFileObject>();
    StandardJavaFileManager fileManager =
        javaCompiler.getStandardFileManager(
            diagnosticCollector, Locale.ENGLISH, Charset.forName("utf-8"));
    try {
      Iterable<? extends JavaFileObject> javaFileObjectsFromFiles =
          fileManager.getJavaFileObjectsFromFiles(files);

      JavaCompiler.CompilationTask task =
          javaCompiler.getTask(
              new StringWriter(), // do not write to System.err
              fileManager,
              diagnosticCollector,
              options,
              null,
              javaFileObjectsFromFiles);

      Boolean success = task.call(); // do NOT inline this variable, call() should complete before
      // errorsToString()
      if (javaErrorFile == null || !javaErrorFile.exists()) {
        Assert.assertTrue(errorsToString(diagnosticCollector, true), success);
      } else {
        assertEqualsToFile(javaErrorFile, errorsToString(diagnosticCollector, false));
      }
    } finally {
      fileManager.close();
    }
  }
Beispiel #3
0
  public TestRun run() {
    StringWriter output = new StringWriter();
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();

    if (debug) {
      System.out.printf(
          "TestInput.run:%n  options: %s%n  processors: %s%n  files: %s%n",
          this.options, this.processors, this.files);
    }

    JavaCompiler.CompilationTask task =
        compiler.getTask(
            output, fileManager, diagnostics, this.options, this.processors, this.files);

    /*
     * In Eclipse, std out and std err for multiple tests appear as one
     * long stream. When selecting a specific failed test, one sees the
     * expected/unexpected messages, but not the std out/err messages from
     * that particular test. Can we improve this somehow?
     */
    Boolean result = task.call();

    return new TestRun(result, output.toString(), diagnostics.getDiagnostics());
  }
Beispiel #4
0
  /**
   * Wow! much faster than compiling outside of VM. Finicky though. Had rules called r and modulo.
   * Wouldn't compile til I changed to 'a'.
   */
  protected boolean compile(String fileName) {
    String classpathOption = "-classpath";

    String[] args =
        new String[] {
          "javac",
          "-d",
          tmpdir,
          classpathOption,
          tmpdir + pathSep + CLASSPATH,
          tmpdir + "/" + fileName
        };
    String cmdLine =
        "javac"
            + " -d "
            + tmpdir
            + " "
            + classpathOption
            + " "
            + tmpdir
            + pathSep
            + CLASSPATH
            + " "
            + fileName;
    // System.out.println("compile: "+cmdLine);

    File f = new File(tmpdir, fileName);
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    //		DiagnosticCollector<JavaFileObject> diagnostics =
    //			new DiagnosticCollector<JavaFileObject>();

    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);

    Iterable<? extends JavaFileObject> compilationUnits =
        fileManager.getJavaFileObjectsFromFiles(Arrays.asList(f));

    Iterable<String> compileOptions =
        Arrays.asList(new String[] {"-d", tmpdir, "-cp", tmpdir + pathSep + CLASSPATH});

    JavaCompiler.CompilationTask task =
        compiler.getTask(null, fileManager, null, compileOptions, null, compilationUnits);
    boolean ok = task.call();

    try {
      fileManager.close();
    } catch (IOException ioe) {
      ioe.printStackTrace(System.err);
    }

    //		List<String> errors = new ArrayList<String>();
    //		for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
    //			errors.add(
    //				String.valueOf(diagnostic.getLineNumber())+
    //				": " + diagnostic.getMessage(null));
    //		}
    //		if ( errors.size()>0 ) {
    //			System.err.println("compile stderr from: "+cmdLine);
    //			System.err.println(errors);
    //			return false;
    //		}
    return ok;

    /*
    File outputDir = new File(tmpdir);
    try {
    	Process process =
    		Runtime.getRuntime().exec(args, null, outputDir);
    	StreamVacuum stdout = new StreamVacuum(process.getInputStream());
    	StreamVacuum stderr = new StreamVacuum(process.getErrorStream());
    	stdout.start();
    	stderr.start();
    	process.waitFor();
              stdout.join();
              stderr.join();
    	if ( stdout.toString().length()>0 ) {
    		System.err.println("compile stdout from: "+cmdLine);
    		System.err.println(stdout);
    	}
    	if ( stderr.toString().length()>0 ) {
    		System.err.println("compile stderr from: "+cmdLine);
    		System.err.println(stderr);
    	}
    	int ret = process.exitValue();
    	return ret==0;
    }
    catch (Exception e) {
    	System.err.println("can't exec compilation");
    	e.printStackTrace(System.err);
    	return false;
    }
    */
  }
  public static boolean compile(
      Collection<String> options,
      final Collection<File> sources,
      Collection<File> classpath,
      Collection<File> platformClasspath,
      Collection<File> sourcePath,
      Map<File, Set<File>> outputDirToRoots,
      final DiagnosticOutputConsumer outConsumer,
      final OutputFileConsumer outputSink,
      CanceledStatus canceledStatus,
      boolean useEclipseCompiler) {
    JavaCompiler compiler = null;
    if (useEclipseCompiler) {
      for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) {
        compiler = javaCompiler;
        break;
      }
      if (compiler == null) {
        outConsumer.report(
            new PlainMessageDiagnostic(
                Diagnostic.Kind.ERROR, "Eclipse Batch Compiler was not found in classpath"));
        return false;
      }
    }

    final boolean nowUsingJavac;
    if (compiler == null) {
      compiler = ToolProvider.getSystemJavaCompiler();
      if (compiler == null) {
        outConsumer.report(
            new PlainMessageDiagnostic(
                Diagnostic.Kind.ERROR, "System Java Compiler was not found in classpath"));
        return false;
      }
      nowUsingJavac = true;
    } else {
      nowUsingJavac = false;
    }

    for (File outputDir : outputDirToRoots.keySet()) {
      outputDir.mkdirs();
    }

    final List<JavaSourceTransformer> transformers = getSourceTransformers();

    final JavacFileManager fileManager =
        new JavacFileManager(
            new ContextImpl(compiler, outConsumer, outputSink, canceledStatus, nowUsingJavac),
            transformers);

    fileManager.handleOption(
        "-bootclasspath", Collections.singleton("").iterator()); // this will clear cached stuff
    fileManager.handleOption(
        "-extdirs", Collections.singleton("").iterator()); // this will clear cached stuff

    try {
      fileManager.setOutputDirectories(outputDirToRoots);
    } catch (IOException e) {
      fileManager.getContext().reportMessage(Diagnostic.Kind.ERROR, e.getMessage());
      return false;
    }

    if (!classpath.isEmpty()) {
      try {
        fileManager.setLocation(StandardLocation.CLASS_PATH, classpath);
        if (!nowUsingJavac && !isOptionSet(options, "-processorpath")) {
          // for non-javac file manager ensure annotation processor path defaults to classpath
          fileManager.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, classpath);
        }
      } catch (IOException e) {
        fileManager.getContext().reportMessage(Diagnostic.Kind.ERROR, e.getMessage());
        return false;
      }
    }
    if (!platformClasspath.isEmpty()) {
      try {
        fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, platformClasspath);
      } catch (IOException e) {
        fileManager.getContext().reportMessage(Diagnostic.Kind.ERROR, e.getMessage());
        return false;
      }
    }
    try {
      // ensure the source path is set;
      // otherwise, if not set, javac attempts to search both classes and sources in classpath;
      // so if some classpath jars contain sources, it will attempt to compile them
      fileManager.setLocation(StandardLocation.SOURCE_PATH, sourcePath);
    } catch (IOException e) {
      fileManager.getContext().reportMessage(Diagnostic.Kind.ERROR, e.getMessage());
      return false;
    }

    //noinspection IOResourceOpenedButNotSafelyClosed
    final LineOutputWriter out =
        new LineOutputWriter() {
          protected void lineAvailable(String line) {
            if (nowUsingJavac) {
              outConsumer.outputLineAvailable(line);
            } else {
              // todo: filter too verbose eclipse output?
            }
          }
        };

    try {
      final Collection<String> _options = prepareOptions(options, nowUsingJavac);

      // to be on the safe side, we'll have to apply all options _before_ calling any of manager's
      // methods
      // i.e. getJavaFileObjectsFromFiles()
      // This way the manager will be properly initialized. Namely, the encoding will be set
      // correctly
      for (Iterator<String> iterator = _options.iterator(); iterator.hasNext(); ) {
        fileManager.handleOption(iterator.next(), iterator);
      }

      final JavaCompiler.CompilationTask task =
          compiler.getTask(
              out,
              fileManager,
              outConsumer,
              _options,
              null,
              fileManager.getJavaFileObjectsFromFiles(sources));

      // if (!IS_VM_6_VERSION) { //todo!
      //  // Do not add the processor for JDK 1.6 because of the bugs in javac
      //  // The processor's presence may lead to NPE and resolve bugs in compiler
      //  final JavacASTAnalyser analyzer = new JavacASTAnalyser(outConsumer,
      // !annotationProcessingEnabled);
      //  task.setProcessors(Collections.singleton(analyzer));
      // }
      return task.call();
    } catch (IllegalArgumentException e) {
      outConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, e.getMessage()));
    } catch (CompilationCanceledException ignored) {
      outConsumer.report(
          new PlainMessageDiagnostic(Diagnostic.Kind.OTHER, "Compilation was canceled"));
    } finally {
      fileManager.close();
      if (nowUsingJavac) {
        cleanupJavacNameTable();
      }
    }
    return false;
  }