Repository: joelittlejohn/jsonschema2pojo
Pull request #513 (2016-02-23 17:26:04)

Jsonschema2pojoRule report problems to STDERR
Capturing diagnostics in the Jsonschema2pojoRule was removing output from STDERR.  This makes that feature optional and adds a test to make sure STDERR output is generated when there are compilation problems.


Patch:
diff --git a/jsonschema2pojo-gradle-plugin/example/java/build.gradle b/jsonschema2pojo-gradle-plugin/example/java/build.gradle
index b9dbb77c..8505c312 100644
--- a/jsonschema2pojo-gradle-plugin/example/java/build.gradle
+++ b/jsonschema2pojo-gradle-plugin/example/java/build.gradle
@@ -1,5 +1,5 @@
-apply plugin: 'java'
 apply plugin: 'jsonschema2pojo'
+apply plugin: 'java'
 
 buildscript {
   repositories {
diff --git a/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaPlugin.groovy b/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaPlugin.groovy
index 3f0aeeff..d61cb79e 100644
--- a/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaPlugin.groovy
+++ b/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaPlugin.groovy
@@ -30,30 +30,32 @@ class JsonSchemaPlugin implements Plugin<Project> {
   public void apply(Project project) {
     project.extensions.create('jsonSchema2Pojo', JsonSchemaExtension)
 
-    if (project.plugins.hasPlugin('java')) {
-      project.tasks.create('generateJsonSchema2Pojo', GenerateJsonSchemaJavaTask)
-    } else if (project.plugins.hasPlugin('com.android.application') || project.plugins.hasPlugin('com.android.library')) {
-      def config = project.jsonSchema2Pojo
-      def variants = null
-      if (project.android.hasProperty('applicationVariants')) {
-        variants = project.android.applicationVariants
-      } else if (project.android.hasProperty('libraryVariants')) {
-        variants = project.android.libraryVariants
-      } else {
-        throw new IllegalStateException('Android project must have applicationVariants or libraryVariants!')
-      }
+    project.afterEvaluate {
+      if (project.plugins.hasPlugin('java')) {
+        project.tasks.create('generateJsonSchema2Pojo', GenerateJsonSchemaJavaTask)
+      } else if (project.android) {
+        def config = project.jsonSchema2Pojo
+        def variants = null
+        if (project.android.hasProperty('applicationVariants')) {
+          variants = project.android.applicationVariants
+        } else if (project.android.hasProperty('libraryVariants')) {
+          variants = project.android.libraryVariants
+        } else {
+          throw new IllegalStateException('Android project must have applicationVariants or libraryVariants!')
+        }
 
-      variants.all { variant ->
+        variants.all { variant ->
 
-        GenerateJsonSchemaAndroidTask task = (GenerateJsonSchemaAndroidTask) project.task(type: GenerateJsonSchemaAndroidTask, "generateJsonSchema2PojoFor${variant.name.capitalize()}") {
-          source = config.source.collect { it }
-          outputDir = project.file("$project.buildDir/generated/source/js2p/$variant.flavorName/$variant.buildType.name/")
-        }
+          GenerateJsonSchemaAndroidTask task = (GenerateJsonSchemaAndroidTask) project.task(type: GenerateJsonSchemaAndroidTask, "generateJsonSchema2PojoFor${variant.name.capitalize()}") {
+            source = config.source.collect { it }
+            outputDir = project.file("$project.buildDir/generated/source/js2p/$variant.flavorName/$variant.buildType.name/")
+          }
 
-        variant.registerJavaGeneratingTask(task, (File) task.outputDir)
+          variant.registerJavaGeneratingTask(task, (File) task.outputDir)
+        }
+      } else {
+        throw new GradleException('generateJsonSchema: Java or Android plugin required')
       }
-    } else {
-      throw new GradleException('generateJsonSchema: Java or Android plugin required')
     }
   }
 }
diff --git a/pom.xml b/pom.xml
index a76fc00e..1d482f7d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -280,6 +280,12 @@
                 <artifactId>jackson-databind</artifactId>
                 <version>2.2.0</version>
             </dependency>
+            <dependency>
+                <groupId>com.github.stefanbirkner</groupId>
+                <artifactId>system-rules</artifactId>
+                <version>1.16.0</version>
+                <scope>test</scope>
+            </dependency>
             <dependency>
                 <groupId>com.google.android</groupId>
                 <artifactId>android</artifactId>


Test patch:
diff --git a/jsonschema2pojo-integration-tests/pom.xml b/jsonschema2pojo-integration-tests/pom.xml
index f088d4fa..0f9434e0 100644
--- a/jsonschema2pojo-integration-tests/pom.xml
+++ b/jsonschema2pojo-integration-tests/pom.xml
@@ -107,6 +107,10 @@
             <artifactId>jsonschema2pojo-ant</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>com.github.stefanbirkner</groupId>
+            <artifactId>system-rules</artifactId>
+        </dependency>
         <dependency>
             <groupId>commons-codec</groupId>
             <artifactId>commons-codec</artifactId>
diff --git a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/CompilerWarningIT.java b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/CompilerWarningIT.java
index 70992698..7a61082e 100644
--- a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/CompilerWarningIT.java
+++ b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/CompilerWarningIT.java
@@ -58,7 +58,7 @@ import static org.hamcrest.MatcherAssert.*;
  */
 @RunWith(Parameterized.class)
 public class CompilerWarningIT {
-  @Rule public Jsonschema2PojoRule schemaRule = new Jsonschema2PojoRule();
+  @Rule public Jsonschema2PojoRule schemaRule = new Jsonschema2PojoRule().captureDiagnostics();
   
   @Parameters(name="{0}")
   public static Collection<Object[]> parameters() {
diff --git a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/util/Jsonschema2PojoRule.java b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/util/Jsonschema2PojoRule.java
index 4bf5bb15..844feba0 100644
--- a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/util/Jsonschema2PojoRule.java
+++ b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/util/Jsonschema2PojoRule.java
@@ -52,11 +52,17 @@ public class Jsonschema2PojoRule implements TestRule {
     private File generateDir;
     private File compileDir;
     private boolean active = false;
+    private boolean captureDiagnostics = false;
     private boolean sourceDirInitialized = false;
     private boolean classesDirInitialized = false;
     private ClassLoader classLoader;
     private List<Diagnostic<? extends JavaFileObject>> diagnostics;
 
+    public Jsonschema2PojoRule captureDiagnostics() {
+      this.captureDiagnostics = true;
+      return this;
+    }
+
     /**
      * Gets the target directory for generate calls.
      *
@@ -102,6 +108,7 @@ public class Jsonschema2PojoRule implements TestRule {
             public void evaluate() throws Throwable {
                 active = true;
                 diagnostics = new ArrayList<Diagnostic<? extends JavaFileObject>>();
+                boolean captureDiagnosticsStart = captureDiagnostics;
                 try {
                     File testRoot = methodNameDir(classNameDir(rootDirectory(), description.getClassName()),
                             description.getMethodName());
@@ -115,6 +122,7 @@ public class Jsonschema2PojoRule implements TestRule {
                     classLoader = null;
                     sourceDirInitialized = false;
                     classesDirInitialized = false;
+                    captureDiagnostics = captureDiagnosticsStart;
                     diagnostics = null;
                     active = false;
                 }
@@ -155,7 +163,8 @@ public class Jsonschema2PojoRule implements TestRule {
         if (classLoader != null) {
             throw new IllegalStateException("cannot recompile sources");
         }
-        classLoader = CodeGenerationHelper.compile(compiler, out, getGenerateDir(), getCompileDir(), classpath, config, new CapturingDiagnosticListener());
+        DiagnosticListener<JavaFileObject> diagnosticListener = captureDiagnostics ? new CapturingDiagnosticListener() : null;
+        classLoader = CodeGenerationHelper.compile(compiler, out, getGenerateDir(), getCompileDir(), classpath, config, diagnosticListener);
         return classLoader;
     }
 
diff --git a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/util/Jsonschema2PojoRuleTest.java b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/util/Jsonschema2PojoRuleTest.java
index 7bc813e9..9d0d4a7c 100644
--- a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/util/Jsonschema2PojoRuleTest.java
+++ b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/util/Jsonschema2PojoRuleTest.java
@@ -17,20 +17,43 @@
 package org.jsonschema2pojo.integration.util;
 
 import java.util.Collection;
+import java.util.List;
 
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.jsonschema2pojo.Schema;
+import org.jsonschema2pojo.rules.RuleFactory;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.contrib.java.lang.system.SystemErrRule;
 import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.codemodel.JDefinedClass;
+import com.sun.codemodel.JExpr;
+import com.sun.codemodel.JMod;
+import com.sun.codemodel.JPackage;
+import com.sun.codemodel.JType;
+
 import edu.emory.mathcs.backport.java.util.Arrays;
 
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.jsonschema2pojo.integration.util.CodeGenerationHelper.config;
+
 @RunWith(Enclosed.class)
 public class Jsonschema2PojoRuleTest {
 
     public static class MethodTests {
+        @Rule
+        public final SystemErrRule systemErrRule = new SystemErrRule().enableLog().mute();
+
         @Rule
         public Jsonschema2PojoRule rule = new Jsonschema2PojoRule();
 
@@ -39,6 +62,33 @@ public class Jsonschema2PojoRuleTest {
             ClassLoader resultsClassLoader = rule.generateAndCompile("/schema/default/default.json", "com.example");
             resultsClassLoader.loadClass("com.example.Default");
         }
+
+        @Test
+        public void compilationProblemsStdErr() {
+          try {
+            rule.generateAndCompile("/schema/default/default.json", "com.example", config("customRuleFactory", BrokenRuleFactory.class.getName()));
+          } catch( Throwable t ) {}
+          assertThat(systemErrRule.getLog(), containsString("return"));
+        }
+
+        public static class BrokenRuleFactory extends RuleFactory {
+          @Override
+          public org.jsonschema2pojo.rules.Rule<JPackage, JType> getObjectRule() {
+            final org.jsonschema2pojo.rules.Rule<JPackage, JType> workingRule = super.getObjectRule();
+
+            return new org.jsonschema2pojo.rules.Rule<JPackage, JType>() {
+              @Override
+              public JType apply(String nodeName, JsonNode node, JPackage generatableType, Schema currentSchema) {
+                JType objectType = workingRule.apply(nodeName, node, generatableType, currentSchema);
+                if( objectType instanceof JDefinedClass ) {
+                  JDefinedClass jclass = (JDefinedClass)objectType;
+                  jclass.method(JMod.PUBLIC, jclass.owner().BOOLEAN, "brokenMethod").body();
+                }
+                return objectType;
+              }
+            };
+          }
+        }
     }
 
     @RunWith(Parameterized.class)