jOOQ / jOOR

jOOR - Fluent Reflection in Java jOOR is a very simple fluent API that gives access to your Java Class structures in a more intuitive way. The JDK's reflection APIs are hard and verbose to use. Other languages have much simpler constructs to access type meta information at runtime. Let us make Java reflection better.
http://www.jooq.org/products
Apache License 2.0
2.81k stars 376 forks source link

Add Reflect.hasField() and Reflect.hasMethod() #70

Open msteinbeck opened 5 years ago

msteinbeck commented 5 years ago

Expected behavior and actual behavior:

Something similar to:

on("qualified.name.of.class")
.hasField("field")
on("qualified.name.of.class")
.hasFieldOfType("field", Integer.class)
on("qualified.name.of.class")
.hasMethod"foo")
on("qualified.name.of.class")
.hasMethodWithParameters"foo", String.class)
on("qualified.name.of.class")
.hasMethodOfType"foo", Void.class)

Steps to reproduce the problem:

Currently not available.

Versions:

lukaseder commented 5 years ago

Thanks for your suggestions. I agree this kind of idea could be useful. What's the specific use-case you have in mind?

lukaseder commented 5 years ago

For the time being, of course, the workaround to check for field existence is to catch the exception if the field doesn't exist.

msteinbeck commented 5 years ago

Thanks for your suggestions. I agree this kind of idea could be useful. What's the specific use-case you have in mind?

We developed a small test suite to (semi)automatically grade our students based on JUnit tests. Sometimes it is necessary to check submissions using reflection. Usually, our tests are two-staged: (1) check if certain fields and/or methods are available, (2) call particular methods with test data. JOOR is well suited for task (2) as it reduced the amount of required boilerplate code. However, it lacks features for task (1). Catching exceptions does not fit our needs because an exception may also be thrown by the student's code. Indeed, we could use other libraries like Javaparser or Spoon to analyze the source code, but sometimes we don't have access to the original source files. In the following you will find some constraints we check in (1):

lukaseder commented 5 years ago

Hmm, your use-case is so specific, why not just write a little wrapper around the reflection API yourself? You will run into edge cases all the time anyway...

While I can see the usage of simple has..() methods (definitely with fields, methods are already much more tricky), I don't see this including modifier checking etc.

msteinbeck commented 5 years ago

While I can see the usage of simple has..() methods (definitely with fields, methods are already much more tricky), I don't see this including modifier checking etc.

If JOOR provides some sort of "has" methods and allows to access the actual reflection API, modifier checking should be straight forward. For example:

on("...")
    .accessField("field") // Checks if field exists and returns Optional<Field>
    .ifPresent(f -> {
        // further checks
    });
lukaseder commented 5 years ago

That's an entirely alternative jOOR that you have in mind. The current jOOR, when calling Reflect.field(), just navigates the metadata information and moves on to the actual instance of the field.

You would like for jOOR to somehow remember that it had accessed a java.lang.reflect.Field, and offer functionality on top of that. And on top of methods. And on top of annotations (eventually). And on top of packages and modules. Surely, that makes sense for some use-cases, but it would require a complete re-design of jOOR. In fact, given how small jOOR currently is, it is akin to creating an entirely new library.

Surely, some other library can already do what you need (e.g. there are libraries and frameworks that allow for querying Java metadata using a SQL like language, such as https://www.jarchitect.com) - or you write a small library yourself. It should really just take 2-3 hours of effort for you, if you scratch your immediate itch. For jOOR, this is too big of a change, I'm afraid. In any case, it cannot be prioritised for your immediate use anyway. Sorry for that.

I'm leaving the hasField() and hasMethod() idea open here on GitHub to collect traction for a potential future implementation.

lukaseder commented 5 years ago

... to give this rejection some additional context: In jOOQ, we do quite a few additional reflection queries that would be generally useful to others, but are very difficult to formalise in an API as focused and simple as jOOR currently is. And that's perfectly OK. It's fine to have some reflection logic outside of jOOR despite having the jOOR dependency.

msteinbeck commented 5 years ago

Ok. Nevertheless, many thanks for your efforts :). hasField() and hasMethod() will already be quite helpful.