Question

Is that possible to give custom warning message in my own API like below? Is Resource leak:'ois' is never closed message related with Java API or JVM?

enter image description here

Was it helpful?

Solution

It's possible using a compiler API. You have to extend an AbstractProcessor and then make sure compiler knows about it.

Lets say we don't like programmers to swear in the source code. So, when someone defines a field with name "shit", we want to show a warning. Here is a simple implementation:

import java.util.List;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;

@SupportedSourceVersion(SourceVersion.RELEASE_7)
@SupportedAnnotationTypes("*")
public class Test extends AbstractProcessor {
    public int shit;
    public int foo;

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        Set<? extends Element> rootElements = roundEnv.getRootElements();

        for (Element element : rootElements) {
            if (element.getKind() == ElementKind.CLASS) {
                List<? extends Element> classElements = element.getEnclosedElements();

                for (Element classElement : classElements) {
                    if (classElement.getKind() == ElementKind.FIELD) {
                        if (classElement.getSimpleName().contentEquals("shit")) {
                            processingEnv.getMessager().printMessage(
                                Kind.WARNING,
                                "How dare you to swear in the source code?!",
                                classElement
                            );
                        }
                    }
                }
            }
        }

        return false;
    }

    public static void main(String[] args) {
        //
    }
}

Now, we want to apply such a processor just for this very class, because there is an ugly bad-called field too.

Using a command line:

javac Test.java
javac -processor Test Test.java

We need to firstly build a processor and then apply it while compiling (in this case to the same file).

And this is the output we get:

Test.java:17: warning: How dare you to swear in the source code?!
    public int shit;
           ^
1 warning

To have the same warning in Eclipse or any other IDE, it's necessary to change compiler settings so it uses this custom processor.

Update: In the comments, kapep sent a link on how to set a custom processor in Eclipse: http://kerebus.com/2011/02/using-java-6-processors-in-eclipse/


Just for the record: Exactly the same warning may be achieved by implementing interface Closeable:

import java.io.Closeable;
import java.io.IOException;

public class Test implements Closeable {
    @Override
    public void close() throws IOException {
        // TODO Auto-generated method stub
    }

    public static void main(String[] args) {
        new Test();
    }
}

And you see the same warning:

enter image description here

OTHER TIPS

You can create warnings, notes, errors and other diagnostic messages like this using an annotation processor. It's a compiler plugin api integrated in the JDK. It lets you analyse the outline structure of source code. Despite the name you don't really need to handle any annotation when processing code. Messages are created using the Messager class. If you provide an element, it will be marked and the message will be shown next to it in the source code editor.

You won't be able to show message on elements inside methods or expressions though, only on declarations like types, properties, methods or parameters. It's possible to additionally parse the method body and generate messages based on the content using other tools, but as far as I know you can't show the message on the actual local element then. You could still show the message on the enclosing method or don't specify any element at all and show it in the IDE's log.

The IDE also needs to support this. I know that Eclipse and NetBeans do support messages generated by annotation processors, but there are probably other modern IDE that do so as well. If you need more features like messages on elements inside method bodies or the quick fix feature as shown in the example, I guess you need to create a plugin for the IDE.

I would believe that it is related to the eclipse ide, you could possibly write a plugin which displays warnings like that.

For example, when you use a method which has the annotation '@Deprecated' the ide automatically tells the programmer that the method is deprecated.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top