Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working with code by cglib (aka dynamically generated code) - such as Spring Framework and MyBatis? #3139

Closed
fzyzcjy opened this issue Mar 8, 2020 · 6 comments
Assignees

Comments

@fzyzcjy
Copy link

fzyzcjy commented Mar 8, 2020

There are some libraries which generate code when running (instead of compiling).

Example 1: Spring framework

Dynamically generated code are very common in the Spring framework... So I do not know whether there will be much more such things hidden in the dark, generating NPEs... For instance:

@RestController class BookController {
    @GetMapping("/books/{name}")
    public List<Book> get(String name, @AuthenticationPrincipal Principal p) {
        p.someMethod(); // bug!
    }
}

There is nowhere directly calling this method at all. Actually, the only guy who will call this, is the dynamically generated code using cglib by Spring. Moreover, the p can be null when Spring calls this, by some manuals of Spring. I think the Checker framework cannot find this bug... :( What can I do?

Example 2: MyBatis

The full code looks like:

public interface BlogMapper {
  @Select("SELECT * FROM blog WHERE id = #{id}")
  Blog selectBlog(int id);
}

and nothing more - no implementation classes or anything more! MyBatis will generate code when starting the application. And note that the result Blog can be null (by their definition)...

What can I do? Thanks so much! I am so sad if I have to not use this wonderful framework, and go to write ugly asserts or checkArguments... :(

@wmdietl
Copy link
Member

wmdietl commented Mar 10, 2020

The Checker Framework operates on Java source code. It doesn't inspect Java bytecode (besides reading type signatures from the classfile) and also doesn't inspect code generated using bytecode libraries like cglib.

In your first example, you could annotate parameter p as @Nullable and the Nullness Checker will give you an error on the illegal dereference in the body.
You would need support from the Spring framework to help you correctly annotate all such parameters as @Nullable.

In the second example, you could annotate the return type as @Nullable and the Nullness Checker will give you an error on illegal dereferences of uses.
Again, you would need support from MyBatis to ensure that for all auto-generated methods the returns are correctly annotated.

Even with these frameworks, you will get some benefits out of using the Checker Framework.
Please let me know if this answered your question

@fzyzcjy
Copy link
Author

fzyzcjy commented Mar 11, 2020

Thanks very much for the reply! I think programmers may forget to annotate each of such things (e.g. the two @Nullables you mentioned... So in such cases, we will still encounter NPEs... :/

@mernst
Copy link
Member

mernst commented Mar 11, 2020

You are right. An analysis tool can only give warnings about the code it analyzes. If there is unanalyzed code, that code might misbehave.

@fzyzcjy
Copy link
Author

fzyzcjy commented Mar 11, 2020

Ah thanks! It is so sad that I may have to go back to use Preconditions.checkNotNull(...) :/

@mernst mernst assigned mernst and unassigned wmdietl Mar 16, 2020
@mernst mernst closed this as completed in abd3548 Mar 17, 2020
@mernst
Copy link
Member

mernst commented Mar 17, 2020

I have added documentation mentioning dynamically generated code as an example of unchecked code. It was not mentioned in the manual previously. Thanks for bringing this up.

@fzyzcjy
Copy link
Author

fzyzcjy commented Mar 17, 2020

You are welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants