swagger-api / swagger-core

Examples and server integrations for generating the Swagger API Specification, which enables easy access to your REST API
http://swagger.io
Apache License 2.0
7.37k stars 2.17k forks source link

Object is not allowed for a model name (e.g. org.mip.mim.Object") #1848

Open rosborne21 opened 8 years ago

rosborne21 commented 8 years ago

Swagger throws a null pointer exception when definining a model with a class name "Object'. For example, I have a data model that includes a class named "org.mip.mim.Object". I have annotated the resource class with Swagger annotations and using swaggers scan capability to build the swagger documentation. When using this name I get the following error:

""Exception in thread "main" java.lang.NullPointerException at io.swagger.models.refs.GenericRef.computeRefFormat(GenericRef.java:93) at io.swagger.models.refs.GenericRef.(GenericRef.java:14) at io.swagger.models.properties.RefProperty.set$ref(RefProperty.java:56) at io.swagger.models.properties.RefProperty.(RefProperty.java:18) at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:109) at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:71) at io.swagger.converter.ModelConverterContextImpl.resolveProperty(ModelConverterContextImpl.java:79) at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:87) at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:71) at io.swagger.converter.ModelConverterContextImpl.resolveProperty(ModelConverterContextImpl.java:79) at io.swagger.jackson.ModelResolver.resolve(ModelResolver.java:342) at io.swagger.jackson.ModelResolver.resolve(ModelResolver.java:127) at io.swagger.converter.ModelConverterContextImpl.resolve(ModelConverterContextImpl.java:99) at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:106) at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:71) at io.swagger.converter.ModelConverterContextImpl.resolveProperty(ModelConverterContextImpl.java:79) at io.swagger.converter.ModelConverters.readAsProperty(ModelConverters.java:58) at io.swagger.jaxrs.Reader.parseMethod(Reader.java:784) at io.swagger.jaxrs.Reader.read(Reader.java:293) at io.swagger.jaxrs.Reader.read(Reader.java:145) at io.swagger.jaxrs.config.BeanConfig.scanAndRead(BeanConfig.java:223) at io.swagger.jaxrs.config.BeanConfig.setScan(BeanConfig.java:204) at org.mitre.lstte.startdata.App.run(App.java:70) at org.mitre.lstte.startdata.App.run(App.java:1) at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:42) at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:76) at io.dropwizard.cli.Cli.run(Cli.java:70) at io.dropwizard.Application.run(Application.java:73) at org.mitre.lstte.startdata.App.main(App.java:81)"

If I use an alternative name, the documentation get's generated correctly. I have tracked the issue to this line of code (If("Object".equals(name)):

 public Model resolve(JavaType type, ModelConverterContext context, Iterator<ModelConverter> next) {
        if (type.isEnumType() || PrimitiveType.fromType(type) != null) {
            // We don't build models for primitive types
            return null;
        }
        final BeanDescription beanDesc = _mapper.getSerializationConfig().introspect(type);
        // Couple of possibilities for defining
        String name = _typeName(type, beanDesc);

        if ("Object".equals(name)) {
            return new ModelImpl();
        }

In the resolveProperty method, A reference property is created with the default ModelImpl() object which has a null name.

resolveProperty(JavaType propType,
                                    ModelConverterContext context,
                                    Annotation[] annotations,
                                    Iterator<ModelConverter> next)

A generic reference (GenericRef) is created, in the RefProperty class using the null name from the model. The null name is referenced in the class GenericRef and throws the null pointer exception.

private static RefFormat computeRefFormat(String ref) {
        RefFormat result = RefFormat.INTERNAL;
        **if (ref.startsWith("http")) {**
            result = RefFormat.URL;
        } else if (ref.startsWith("#/")) {
            result = RefFormat.INTERNAL;
        } else if (ref.startsWith(".") || ref.startsWith("/")) {
            result = RefFormat.RELATIVE;
        }

        return result;
    }

Is using the Object as a class name not allowed? I do not have much flexibility as I am implementing an international standard. Can I remove the line of code that leads to the empty ModelImpl? Or perhaps, set the name on it?

Any help would be appreciated.

V/R, Rick Osborne

webron commented 8 years ago

Using Object as a class name is allowed, it's pretty much a bug. I guess we didn't take into account someone may go that road, considering Java's Object.