NPE in JsonBuildHelper
muyuanjin opened this issue · comments
muyuanjin commented
Your Environment(您的使用环境,您期望的结果,社区已开启国际化推广,请文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)
- smart-doc version: 3.0.4
- plugin version (e.g. smart-doc-maven-plugin or smart-doc-gradle-plugin): 3.0.4
- build tool version(maven or gradle): maven 3.9.5
- jdk version: 17
Expected Behavior(您期望的结果,社区已开启国际化推广,请用文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)
Current Behavior(当前结果,社区已开启国际化推广,请用文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)
[ERROR]
java.lang.NullPointerException: Cannot invoke "String.length()" because "fieldGicName" is null
at com.ly.doc.helper.JsonBuildHelper.buildJson (JsonBuildHelper.java:395)
at com.ly.doc.template.IRestDocTemplate.requestParams (IRestDocTemplate.java:643)
at com.ly.doc.template.IRestDocTemplate.buildEntryPointMethod (IRestDocTemplate.java:452)
at com.ly.doc.template.IRestDocTemplate.processApiData (IRestDocTemplate.java:96)
at com.ly.doc.template.SpringBootDocBuildTemplate.renderApi (SpringBootDocBuildTemplate.java:53)
at com.ly.doc.template.IDocBuildTemplate.getApiData (IDocBuildTemplate.java:51)
at com.ly.doc.builder.HtmlApiDocBuilder.buildApiDoc (HtmlApiDocBuilder.java:71)
at com.ly.doc.plugin.mojo.HtmlMojo.executeMojo (HtmlMojo.java:48)
at com.ly.doc.plugin.mojo.BaseDocsGeneratorMojo.execute (BaseDocsGeneratorMojo.java:168)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:126)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:328)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:73)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:53)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:118)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:261)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:906)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:283)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:206)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:568)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:283)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:226)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:407)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:348)
at org.codehaus.classworlds.Launcher.main (Launcher.java:47)
Possible Solution(bug解决建议,社区已开启国际化推广,请用文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)
Steps to Reproduce (Bug产生步骤,请尽量提供用例代码。社区已开启国际化推广,请用文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)
The "field" that raises NPE is located in the default method with generics of an interface under annotation. :
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@JacksonAnnotationsInside
@JsonSerialize(using = Enums.EnumsJsonSerializer.class)
@JsonDeserialize(using = Enums.EnumsJsonDeserializer.class)
public @interface Enums {
//...
interface Serialize<T extends Enum<T> & Serialize<T>> {
default String getSerializationName() {
return ((Enum<?>) this).name();
}
default Integer getSerializationId() {
return ((Enum<?>) this).ordinal();
}
@SuppressWarnings("unchecked")
default Class<T> getOriginalClass() { // this "field" causes NPE
return (Class<T>) this.getClass();
}
//...
}
//...
}
Context(Bug影响描述,社区已开启国际化推广,请用文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)
kalman03 commented
try it with apideploy?
孙宇 commented
@muyuanjin Could you provide a more detailed use case to assist the community in more effectively resolving issues? If you could help fix this problem, we would greatly welcome your contribution.
muyuanjin commented
The following is a local test that can reproduce this problem :
/**
* com.ly.doc.helper.JsonBuildHelper#buildJson
* issue:NPE in JsonBuildHelper #789
*/
@Test
void testBuildJsonWithNPE() throws IOException {
ApiConfig apiConfig = new ApiConfig();
JavaProjectBuilder projectBuilder = JavaProjectBuilderHelper.create();
Assertions.assertNotNull(projectBuilder.getClassByName(getClass().getName()));
JavaClass taskType = projectBuilder.getClassByName(Task.class.getName());
Assertions.assertNotNull(taskType);
Assertions.assertFalse(taskType.getMethods().isEmpty());
ProjectDocConfigBuilder builder = new ProjectDocConfigBuilder(apiConfig, projectBuilder);
Assertions.assertNull(builder.getClassByName(getClass().getName()));
Assertions.assertNotNull(builder.getClassByName(Task.class.getName()));
Assertions.assertFalse(builder.getClassByName(Task.class.getName()).getMethods().isEmpty());
JsonBuildHelper.buildJson(Task.class.getName(),
Task.class.getCanonicalName(),
false, 0, new HashMap<>(16), new HashSet<>(), builder
);
}
interface Serialize<T extends Serialize<T>> {
default String getSerializationName() {
return ((Enum<?>) this).name();
}
default Integer getSerializationId() {
return ((Enum<?>) this).ordinal();
}
@SuppressWarnings("unchecked")
default Class<T> getOriginalClass() {
return (Class<T>) this.getClass();
}
}
public static class Task implements Serialize<Task> {
private String taskType;
public String getTaskType() {
return taskType;
}
public void setTaskType(String taskType) {
this.taskType = taskType;
}
}