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

[master] IndexOutOfBoundsException with generic superclass #58

Closed
darylteo opened this issue Jun 11, 2016 · 5 comments
Closed

[master] IndexOutOfBoundsException with generic superclass #58

darylteo opened this issue Jun 11, 2016 · 5 comments

Comments

@darylteo
Copy link

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.rangeCheck(ArrayList.java:653)
        at java.util.ArrayList.get(ArrayList.java:429)
        at com.sebastian_daschner.jaxrs_analyzer.model.JavaUtils.getTypeVariables(JavaUtils.java:340)
        at com.sebastian_daschner.jaxrs_analyzer.model.JavaUtils.resolvePotentialTypeVariables(JavaUtils.java:433)
        at com.sebastian_daschner.jaxrs_analyzer.model.JavaUtils.getReturnType(JavaUtils.java:326)
        at com.sebastian_daschner.jaxrs_analyzer.analysis.results.JavaTypeAnalyzer.mapGetter(JavaTypeAnalyzer.java:196)
        at com.sebastian_daschner.jaxrs_analyzer.analysis.results.JavaTypeAnalyzer.lambda$analyzeClass$3(JavaTypeAnalyzer.java

Took me awhile to figure out what was happening. The type analyzer does not handle concrete subclasses of generic types. Not sure if this is fixable in its current state due to erasure but I'll give it another crack tomorrow.

Code fails to identify the generic return type of getData().


// lombok generating getters and setters
@Data
public abstract class Json<T> {
    private T data;
}

@Path("/resource")
@Produces("application/json")
public class SomeResource {
    @GET
    public Many findAll() {
       ...
    }

    public static class Many extends Json<List<ResourceEntity>> {
    }

Use case:

  • standardised return types for all endpoints (success, errors, JSONAPI spec stuff etc.)
  • concrete models for swagger spec (above generates nice class names like SomeResourceMany). Returning Json<List> leads to weird behaviour as well (separate issue for another time)
@darylteo darylteo changed the title [master] Array [master] IndexOutOfBoundsException with generic superclass Jun 12, 2016
@darylteo
Copy link
Author

darylteo commented Jun 12, 2016

Battled this for a day, can't see a really good out, due to shitty generics.

In the meantime, I've managed to stop the exception by using the following code:

    private static Map<String, String> getTypeVariables(final String type) {
        final Map<String, String> variables = new HashMap<>();
        final List<String> actualTypeParameters = getTypeParameters(type);
        final Class<?> loadedClass = loadClass(toClassName(type));
        if (loadedClass == null) {
            LogProvider.debug("could not load class for type " + type);
            return Collections.emptyMap();
        }

        final TypeVariable<? extends Class<?>>[] typeParameters = loadedClass.getTypeParameters();
        for (int i = 0; i < actualTypeParameters.size(); i++) {
            variables.put(typeParameters[i].getName(), actualTypeParameters.get(i));
        }
        return variables;
    }

JavaTypeAnalyzer does not pass in a generic signature for superclass, so while there are expected parameters (such as T), the type information is simply not in the classname after erasure.

I'll keep this in my local fixes for now. Let me know if you want a PR.

darylteo pushed a commit to darylteo/jaxrs-analyzer that referenced this issue Jul 24, 2016
@darylteo
Copy link
Author

@sdaschner just did another similar repro for this issue.

@sdaschner
Copy link
Owner

sdaschner commented Aug 6, 2016

Looked further into it and of course you were right. Changed that line but we should in general add more generic tests, maybe in the system test project...

Thanks!

@darylteo
Copy link
Author

darylteo commented Aug 6, 2016

Haven't really had the time to look into the system tests, sorry. Not really sure how it fits in with this repository (do I need to mvn install it and have mvn pick it up as a plugin or something?).

Being able to run the tests in intellij while I'm developing is easier for me currently obviously.

of course you were right

Thanks! I'm flattered ;)

@sdaschner
Copy link
Owner

sdaschner commented Aug 6, 2016

The reason for the system test is that we don't want to loose any test scenarios in which we invested time. Running in the IDE is more productive, yes, but how about having some (temporary) tests in the IDE and then moving it to the system test project after fixing it -- as regression tests?

The system test project takes the Analyzer from either Maven central (snapshot) or your local version in your Maven repository. So if you build a new JAX-RS Analyzer version via mvn clean install that will be taken when you run the system test project with ./run-test.js.

Hehe, well deserved :)

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

2 participants