DrJavaAtRice / drjava

Branches for integration and releases
20 stars 28 forks source link

Move DrJava to programmatic compilation #23

Closed barretg closed 6 months ago

barretg commented 7 months ago

Background

"Prior to Java 6, DrJava was forced to treat Java compilers as completely separate libraries that DrJava dynamically discovered in the file system each time it was executed. It had to cope with the fact that there were several different versions of Java in use and several different compilers (with different APIs) for each version.

After Sun/Oracle became committed to supporting a solid comprehensive open source implementation of Java and access to the compiler was provided as part of the core Java libraries in Java 6, Sun/Oracle was forced to release the compiler (perhaps without some proprietary bits) to the open-source world. At this point, we could potentially change course, but the funding for the DrJava project (which started in 2000) ended before this juncture.

So we have limped along with the old framework. What I want to do now is only support the compiler in the library of the running JVM. How simple this approach is in principle in comparison to what DrJava has been doing in the past. Most of the existing infrastructure can be discarded if we can figure out how to cleanly cut it out. In some sense, the default compiler will become the only compiler but it will be accessed as part of the Java core libraries (namely in javax.tools), which in principle is much simpler. There is no searching and only one interface (as specified in Java documentation starting with Java 8). Programmatic access to the compiler was added to the Java libraries in Java 6, but we only need to support Java 8+, and each edition of Java typically adds more content (in backwards-compatible fashion) so do not need to worry about the differences between Java 6 and Java 8. We can Java 8 as the standard to which we will program and that content will be preserved in all future editions of Java (at least that has been the mantra of the Java platform).

I suggest that we initially add support for the library compiler in place of the existing default compiler embedded in drjava.jar (as tools.jar from a particular open-source distribution)." -- Corky

TODO:

barretg commented 7 months ago

Some relevant links: Programmatic compilation stack-overflow Setting classpath when doing programmatic compilation stack-overflow Java 8 docs

barretg commented 7 months ago

It appears that programmatic compilation is ONLY available when running in a JDK, so this will require that DrJava be run in a JDK and not just a JRE, which is an acceptable requirement IMO, given that it's an IDE.

barretg commented 7 months ago

@ponderosaTX Could you post a quick rundown of relevant portions of the codebase to get us started in the right direction? Thanks.

EDIT: in OH he said "anything that mentions the word 'Compiler' is going to be relevant"

barretg commented 7 months ago

The primary directory we'll need to make changes in is: drjava/src/edu/rice/cs/drjava/model/compiler

We'll want to decide on an implementation that extends the CompilerInterface interface and figure out if we need to implement a new CompilerModel to switch to when using the programmatic compilation option.

We'll use the JavaCompiler interface (the user's compiler can be retrieved with JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); Source

Here's a bunch of examples using the library.

We'll probably need to figure out if we want to swap out the current DefaultCompilerModel for a new one, or if we can make our compilation method use the same interfaces that it expects.

We'll need to decide if we want this to be the only way to compile things or if we still want to support user supplied compilers.

barretg commented 7 months ago

As per in class: this will be the new ONLY way to compile in DrJava, so we can remove the compiler selection panel in drjava/src/edu/rice/cs/drjava/ui/CompilerErrorPanel.java

barretg commented 7 months ago

One concern I had: Will programmatic compilation be properly sandboxed if it's using the same instance that DJ itself is running on? What does it look like to do development on say DJ itself where the classes are the ones currently loaded. Will compiling shadow the currently loaded DJ files?

ponderosaTX commented 7 months ago

Since the DrJava build process is performed "externally" using ant rather than internally within DrJava, the compiler runs in a completely different JVM than DrJava does. Whatever instances (perhaps none) of DrJava are running when a new DrJava jar file is created using ant are invisible to the build process. In contrast, the DrJava compile command compiles Java code inside the main JVM running DrJava. In this context, shadowing is a major issue. Fortunately in this project, the shadowing issue should not arise.

barretg commented 6 months ago

javaxtools-compile-test now has a working implementation of the javax.tools compiler, but it has not yet been thoroughly tested

barretg commented 6 months ago

These 5 unit tests fail:

barretg commented 6 months ago

Removed the -xlint flag from compilation and now only this test is failing:

    [junit] Testcase: testCompileFailsCorrectLineNumbers(edu.rice.cs.drjava.model.GlobalModelCompileErrorsTest):    FAILED
    [junit] location of first error should be between 20 and 29 inclusive (line 2), but was 32
    [junit] junit.framework.AssertionFailedError: location of first error should be between 20 and 29 inclusive (line 2), but was 32
    [junit]     at edu.rice.cs.drjava.model.GlobalModelCompileErrorsTest.testCompileFailsCorrectLineNumbers(GlobalModelCompileErrorsTest.java:333)
barretg commented 6 months ago

All test cases now pass https://github.com/DrJavaAtRice/drjava/pull/25

barretg commented 6 months ago

Let's talk Wednesday and see if we can't merge into master this week. I want to resolve the ant run issue Corky was having first.

barretg commented 6 months ago

Fixed the logic to pass the build directory to the library compiler.

Turns out you can’t just pass it the ‘-d’ command line arg, but instead need to set StandardLocation.CLASS_OUTPUT in the file manager for it to find the build dir. This seems to be working well now.