Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to give warning message in own API?

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

like image 934
Can Mingir Avatar asked Apr 22 '14 14:04

Can Mingir


People also ask

How do you display errors in API?

When writing your Web API, use a 404 to generate an error to inform the programmer calling your API that they have requested a piece of data that's not available in your data store. For example, they may pass the following request to your Get method; api/Product/999.

How does REST API handle error response?

The most basic way of returning an error message from a REST API is to use the @ResponseStatus annotation. We can add the error message in the annotation's reason field. Although we can only return a generic error message, we can specify exception-specific error messages.


2 Answers

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

like image 167
tzima Avatar answered Oct 23 '22 10:10

tzima


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.

like image 1
kapex Avatar answered Oct 23 '22 10:10

kapex