question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Question] Load Generic Types

See original GitHub issue

Hey folks,

I’m using classgraph in a project and I just got stuck in a scenario with generic types.

Here’s the scenario:

@MyAnnotation
public class MyClass implements MyInterface<Type1, Type2> {

}

Steps to perform:

1 - Find all classes annotated with @MyAnnotation; 2 - Check if the class implements the interface MyInterface; 3 - Get the parameterized input and output(Type1 and Type2) classes.

I was able to accomplish this with the following code:

ScanResult scanResult = new ClassGraph()
    .enableAllInfo()
    .whitelistPackages("my.package")
    .scan();

String annotationClassName = MyAnnotation.class.getCanonicalName();
ClassInfoList routes = scanResult.getClassesWithAnnotation(annotationClassName);

for (ClassInfo info : routes) {
    ClassTypeSignature typeSignature = info.getTypeSignature();

    for (ClassRefTypeSignature ref : typeSignature.getSuperinterfaceSignatures()) {

        if (MyInterface.class.getName().equals(ref.getBaseClassName())) {
            List<TypeArgument> args = ref.getTypeArguments();
            Class<?> inputClass = Class.forName(args.get(0).toString());
            Class<?> outputClass = Class.forName(args.get(1).toString());
        } 

    }
}

This works fine for non-generic types, but if I have an implementation like:

@MyAnnotation
public class MyClass implements MyInterface<Type1, List<Type2>> {

}

This code won’t work because the object doesn’t know about its generic type at execution time, so when I try Class.forName(args.get(1).toString()) I’ll get ClassNotFoundException.

So my question is: Is there a better approach using classgraph to accomplish these 3 steps? Does classgraph offers a loadClass() method for TypeArgument?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
lukehutchcommented, Sep 1, 2018

Turns out this is extremely complex. If you have class X<Y, Z extends List & Y> extends S<Z>, then the fields of type Z in class S have the type bounds of extends List implements Y, and there’s no way to declare this type in Java source (you can only write code where the field conforms to one of List or Y). It gets even more complex, when it comes to determining concrete types of methods and fields, when you start bringing in default methods in interfaces (JDK 8+) and other factors.

So actually I’m going to punt the resolution of generic types to the user, if they care enough to resolve type arguments using type parameters.

I’ll also make a note in the Javadoc for ClassInfo#getMethodInfo() and ClassInfo#getFieldInfo() that only declared methods and fields are returned – you need to iterate to supertypes to get all methods/fields.

0reactions
lukehutchcommented, Aug 31, 2018

The old API will remain. If you need properly resolved types, you can use the new calls. They will be a bit slower than the old calls, but you can’t put a price on correctness. And the increase in time to compute the right type info will be nothing compared to the I/O time already needed to read the classfiles in the first place.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Generic Types - Learning the Java Language
A generic type is a generic class or interface that is parameterized over types. The following Box class will be modified to demonstrate...
Read more >
Loading a generic type by name when the ... - Stack Overflow
Parse the type name into the type definition and the generic type arguments. Obtain the generic type definition object; Obtain the type objects ......
Read more >
Java Generics Example Tutorial - Generic Method, Class ...
A generic type is a class or interface that is parameterized over types. ... Question mark (?) is the wildcard in generics and...
Read more >
10 Interview Questions on Java Generics for Programmer and ...
1. What is Generics in Java? · 2. How Generics works in Java ? · 3. What is Bounded and Unbounded wildcards in...
Read more >
Generic Class in Java - GeeksforGeeks
Generic means parameterized types. Using generics, the idea is to allow any data type to be it Integer, String, or any user-defined ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found