0

I'm trying to make an EasyPrint class that allows you to print to the console with just print(), println(), and printf(), instead of having to do System.out or out. It also lets you set it to use a different PrintStream or a PrintWriter. However, when I test it, I get this error:

Exception in thread "main" java.lang.RuntimeException: Uncompilable code
    at easyprint.EasyPrint.print(EasyPrint.java:1)
    at tests.TestEasyPrint.main(TestEasyPrint.java:15)
C:\Users\myUsername\AppData\Local\NetBeans\Cache\17\executor-snippets\run.xml:111: The following error occurred while executing this line:
C:\Users\myUsername\AppData\Local\NetBeans\Cache\17\executor-snippets\run.xml:68: Java returned: 1
BUILD FAILED (total time: 0 seconds)

As you can see, it doesn't provide any information about the problem besides the run.xml stuff, which I don't understand.

Here's a shortened version of the class and the test that has the same problem:

import java.io.*;

public class ShortEasyPrint {
    private static Object output = System.out;
    
    public static void setOutput(PrintStream output) {
        ShortEasyPrint.output = output;
    }
    
    public static void setOutput(PrintWriter output) {
        ShortEasyPrint.output = output;
    }

    public static void print(String s) {
        if (output instanceof PrintStream printStream)
            printStream.print(s);
        else if (output instanceof PrintWriter printWriter)
            printWriter.print(s);
    }
    
    public static void main(String[] args) {
        print("Test");
    }
}

I've tried putting the test program in the same package, and the same class too (like in the example), and it still doesn't work (of course, even if they did work there, I wouldn't be able to use the class for other programs). I put the run.xml in pastebin, in case it helps: https://pastebin.com/zMYe78SN

Does anyone know what's wrong?

Choosechee
  • 73
  • 7
  • What is `run.xml`? – Basil Bourque May 08 '23 at 03:01
  • You have not defined `out`. – Basil Bourque May 08 '23 at 03:03
  • We need an entire example, as brief as possible to show your issue. [MCVE](https://stackoverflow.com/help/minimal-reproducible-example) – Basil Bourque May 08 '23 at 03:04
  • @BasilBourque out is System.out, I just imported it, so it would just be out. – Choosechee May 08 '23 at 03:09
  • I've added a better example. – Choosechee May 08 '23 at 03:22
  • I am running NB 17 with Java 20 on Windows 10, and could not reproduce your problem; your code ran fine. Then I compared your run.xml with mine. Mine is about twice as large as yours, but yours does contain valid XML. So then I replaced my copy of run.xml with yours, and restarted NetBeans. Your code still ran fine! So although that doesn't resolve your issue, it does show that your code and your run.xml are OK, and the problem lies elsewhere. What version of Java are you using? – skomisa May 08 '23 at 05:01
  • I can reproduce the problem using Netbeans 17 and Java 17 on Windows 10 – Peter F May 08 '23 at 05:55
  • Fixed in NetBeans 18; tested with Java/FX 17 on macOS; see [PR-5682](https://github.com/apache/netbeans/pull/5682). – trashgod Jun 10 '23 at 23:31

2 Answers2

1

Although I can't reproduce your problem, I think it is occurring because of a bug in NetBeans. See Uncompilable code exception with Compile on Save #5260.

That bug report cites using instanceof pattern matching as a trigger for that "Uncompilable code" error, and also using the "Compile on save" build option. So here are a couple of changes you can make to avoid the issue:

[1] Change your print() method to not use the instanceof pattern matching syntax:

public static void print(String s) {
    if (ShortEasyPrint.output instanceof PrintStream) {
        PrintStream printStream = (PrintStream)output;
        printStream.print(s);
    } else if (ShortEasyPrint.output instanceof PrintWriter) {
        PrintWriter printWriter = (PrintWriter)output;
        printWriter.print(s);
    }
}

(There are other ways to implement that logic, but that is irrelevant with respect to your problem.)

[2] Uncheck {project} > Properties > Build > Compiling > Compile on Save if it is currently checked.

Notes:

  • I'm not sure why I can't reproduce your problem. Your code runs fine for me, and I'm also using Compile on Save. Perhaps it is because I'm using JDK 20, and you are using an earlier JDK?
  • While not directly related to your issue, JEP 433: Pattern Matching for switch (Fourth Preview) may be of interest. In particular, see the code in the formatterPatternSwitch() example.
  • Arguably, your question is a duplicate of java.lang.RuntimeException: Uncompilable source code - what can cause this?, although that question lacked the detail and focus of yours. But you still may want to review its answers if this answer doesn't resolve your issue.
skomisa
  • 16,436
  • 7
  • 61
  • 102
1

It's a bug in Netbeans IDE.

See these two issues on Github:

Workarounds:

  • Disable the 'Compile on Save' feature in Netbeans IDE.

    1. Open the 'Project Properties' window. You can right-click on the project in the Projects panel then choose Properties, or click File > Project Properties.
    2. Click Build > Compiling.
    3. At the top, de-select 'Compile on Save' then click OK.

    screenshot of Project Properties window

    After turning off 'Compile on Save', the project will have a hammer icon and all the Java files in the project will have a wrench icon:

    screenshot of project and file in Netbeans with Compile On Save turned off

  • Do not use instanceof pattern matching. You can change the code to:

    public static void print(String s) {
        if (output instanceof PrintStream) {
            PrintStream castToPrintStream = (PrintStream) output;
            castToPrintStream.print(s);
        } else if (output instanceof PrintWriter) {
            PrintWriter castToPrintWriter = (PrintWriter) output;
            castToPrintWriter.print(s);
        }
    }
    

    or

    public static void print(String s) {
        if (output instanceof PrintStream) {
            ((PrintStream) output).print(s);
        } else if (output instanceof PrintWriter) {
            ((PrintWriter) output).print(s);
        }
    }
    
  • Do not use Netbeans IDE. You can compile and run your code using the command-line like this:

    javac ShortEasyPrint.java
    java ShortEasyPrint
    

    Links to documentation:

Peter F
  • 137
  • 8
  • How is this answer any different to the one I have already posted? (Apart from telling the OP not to use NetBeans, which is not a solution.) – skomisa May 08 '23 at 06:42
  • It is no different. I started writing it before you posted your answer. – Peter F May 08 '23 at 06:44