Bug 531305: Canonical model generator fails to run on JDK9 - test

Signed-off-by: Lukas Jungmann <lukas.jungmann@oracle.com>
Reviewed-by: TomasK, RomanG
diff --git a/jpa/eclipselink.jpa.test.jse/.classpath b/jpa/eclipselink.jpa.test.jse/.classpath
index 3bf9731..57289be 100644
--- a/jpa/eclipselink.jpa.test.jse/.classpath
+++ b/jpa/eclipselink.jpa.test.jse/.classpath
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
 	<classpathentry kind="src" path="src"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.persistence.core"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/eclipselink.core.test"/>
@@ -11,5 +11,6 @@
 	<classpathentry kind="var" path="ECLIPSELINK_HOME/plugins/javax.transaction_1.1.0.v201002051055.jar" sourcepath="/ECLIPSELINK_HOME/plugins/javax.transaction/src"/>
 	<classpathentry kind="var" path="ECLIPSELINK_HOME/plugins/org.eclipse.persistence.antlr_3.5.2.v201711011707.jar" sourcepath="/ECLIPSELINK_HOME/plugins/org.eclipse.persistence.antlr.source_3.5.2.v201711011707.jar"/>
 	<classpathentry kind="var" path="ECLIPSELINK_HOME/plugins/org.eclipse.persistence.asm_6.0.0.v201710052159.jar" sourcepath="/ECLIPSELINK_HOME/plugins/org.eclipse.persistence.asm.source_6.0.0.v201710052159.jar"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.persistence.jpa.modelgen"/>
 	<classpathentry kind="output" path="classes"/>
 </classpath>
diff --git a/jpa/eclipselink.jpa.test.jse/.settings/org.eclipse.jdt.core.prefs b/jpa/eclipselink.jpa.test.jse/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..0c68a61
--- /dev/null
+++ b/jpa/eclipselink.jpa.test.jse/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/jpa/eclipselink.jpa.test.jse/antbuild.properties b/jpa/eclipselink.jpa.test.jse/antbuild.properties
index 6fb2fe8..a1cdfbf 100644
--- a/jpa/eclipselink.jpa.test.jse/antbuild.properties
+++ b/jpa/eclipselink.jpa.test.jse/antbuild.properties
@@ -11,7 +11,7 @@
 javac.debuglevel=lines,vars,source
 
 # Edit this property when you would like to override the java version during testing
-javac.version=1.6
+javac.version=1.8
 
 # Edit this property to increase the maxMemory heap memory used by the tests if you get an OutOfMemoryException - use JConsole.exe to triage the memory spike at the end of the test
 # The current default is 768m (the LC "m" is required")
diff --git a/jpa/eclipselink.jpa.test.jse/antbuild.xml b/jpa/eclipselink.jpa.test.jse/antbuild.xml
index 71deab1..ba8188c 100644
--- a/jpa/eclipselink.jpa.test.jse/antbuild.xml
+++ b/jpa/eclipselink.jpa.test.jse/antbuild.xml
@@ -17,6 +17,7 @@
     <property name="jse.classes.dir"        value="${basedir}/classes" />
     <!-- Use common property name to allow override -->
     <property name="reports.dir"            value="${basedir}/reports" />
+    <property name="jse.run.dir"            value="${basedir}/run" />
     
     <property name="jse.el.plugins.dir"     value="${jse.el.root}/plugins"/>
     <property name="jse.jpa.plugins.dir"    value="${jse.jpa.root}/plugins"/>
@@ -26,7 +27,9 @@
     <property name="javax.transaction" value="${jse.el.plugins.dir}/javax.transaction_1.1.0.v201002051055.jar"/>
     <property name="javax.validation" value="${jse.el.plugins.dir}/javax.validation.api_2.0.1.Final.jar"/>
     <property name="javax.persistence" value="${jse.jpa.plugins.dir}/javax.persistence_2.2.0.v201708071007.jar"/>
-   
+    <property name="jse.modelgen.jar" value="${jse.el.plugins.dir}/org.eclipse.persistence.jpa.modelgen_3.0.0.qualifier.jar"/>
+
+    <property environment="env" />
     <property file="${user.home}/build.properties"/>
     <property file="${test.properties}" />
     <property file="./antbuild.properties" />
@@ -37,7 +40,8 @@
     <property name="test.junit.jvm.exec" value="${test.junit.jvm}/bin/java"/>
 
     <path id="compile.jse.path">
-        <pathelement path="${jse.el.root}/eclipselink.jar" />
+        <pathelement path="${jse.eclipselink.jar}" />
+        <pathelement path="${jse.modelgen.jar}" />
         <pathelement path="${javax.transaction}" />
         <pathelement path="${javax.validation}" />
         <pathelement path="${javax.persistence}" />
@@ -46,6 +50,7 @@
     <path id="run.jse.path">
         <pathelement path="${jse.classes.dir}" />
         <pathelement path="${jse.eclipselink.jar}" />
+        <pathelement path="${jse.modelgen.jar}" />
         <pathelement path="${javax.transaction}" />
         <pathelement path="${javax.validation}" />
         <pathelement path="${javax.persistence}" />
@@ -73,6 +78,7 @@
     
     <target name="test-run" depends="compile, weave">
         <mkdir dir="${reports.dir}"/>
+        <mkdir dir="${jse.run.dir}"/>
         <property name="rmi.port" value="1099"/>
         <property name="additional.jvmargs" value="-Ddummy2=dummy"/>
         <property name="debugargs" value="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=7777"/>
@@ -84,6 +90,7 @@
             <sysproperty key="javax.persistence.jdbc.user" value="${db.user}"/>
             <sysproperty key="javax.persistence.jdbc.password" value="${db.pwd}"/>
             <sysproperty key="rmi.port" value="${rmi.port}"/>
+            <sysproperty key="run.dir" value="${jse.run.dir}"/>
             <classpath>
                 <path refid="run.jse.path" />
             </classpath>
@@ -129,12 +136,14 @@
         </copy>
 
         <javac debug="true" destdir="${jse.classes.dir}" includeantruntime="false" source="${javac.version}" target="${javac.version}">
+            <compilerarg value="-proc:none"/>
             <classpath refid="compile.jse.path"/>
             <src path="src"/>
         </javac>
     </target>
     <target name="clean">
         <delete dir="${jse.classes.dir}" />
+        <delete dir="${jse.run.dir}" />
         <delete dir="${reports.dir}" />
     </target>
 
diff --git a/jpa/eclipselink.jpa.test.jse/src/org/eclipse/persistence/jpa/test/modelgen/TestProcessor.java b/jpa/eclipselink.jpa.test.jse/src/org/eclipse/persistence/jpa/test/modelgen/TestProcessor.java
new file mode 100644
index 0000000..c0b3c8c
--- /dev/null
+++ b/jpa/eclipselink.jpa.test.jse/src/org/eclipse/persistence/jpa/test/modelgen/TestProcessor.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     02/17/2018-2.7.2 Lukas Jungmann
+ *       - 531305: Canonical model generator fails to run on JDK9
+ ******************************************************************************/
+package org.eclipse.persistence.jpa.test.modelgen;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URL;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.StandardOpenOption;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Arrays;
+import java.util.Collections;
+
+import javax.persistence.Entity;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestProcessor {
+
+    @BeforeClass
+    public static void prepare() throws IOException {
+        File testRoot = new File(System.getProperty("run.dir"));
+        if (testRoot.exists() && testRoot.isDirectory()) {
+            for (File testDir: testRoot.listFiles()) {
+                delete(testDir);
+            }
+        }
+    }
+    
+    @Test
+    public void testProc() throws Exception {
+        File runDir = new File(System.getProperty("run.dir"), "testproc");
+        File srcOut = new File(runDir, "src");
+        srcOut.mkdirs();
+        File cpDir = new File(runDir, "cp");
+        cpDir.mkdirs();
+        File pxml = new File(cpDir, "META-INF/persistence.xml");
+        pxml.getParentFile().mkdirs();
+        try (BufferedWriter writer = Files.newBufferedWriter(pxml.toPath(), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) {
+            writer.write(PXML, 0, PXML.length());
+        } catch (IOException x) {
+            throw x;
+        }
+        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
+
+        StandardJavaFileManager sfm = compiler.getStandardFileManager(diagnostics, null, null);
+        URL apiUrl = Entity.class.getProtectionDomain().getCodeSource().getLocation();
+        sfm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(new File(apiUrl.getFile()), cpDir));
+        sfm.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(srcOut));
+        sfm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(cpDir));
+
+        TestFO entity = new TestFO("org.Sample",
+                "package org; import javax.persistence.Entity; @Entity public class Sample { public  Sample() {} public int getX() {return 1;}}");
+        TestFO nonEntity = new TestFO("org.NotE",
+                "package org; import javax.persistence.Entity; public class NotE extends some.IF { public  NotE() {} @custom.Ann public external.Cls getW() {return new Object();}}");
+        TestFO generated8 = new TestFO("org.Gen8",
+                "package org; import javax.annotation.Generated; @Generated(\"com.example.Generator\") public class Gen8 { public  Gen8() {} public int getY() {return 42;}}");
+        TestFO generated9 = new TestFO("org.Gen9",
+                "package org; @javax.annotation.processing.Generated(\"com.example.Generator\") public class Gen9 { public  Gen9() {} public int getZ() {return 9*42;}}");
+        CompilationTask task = compiler.getTask(new PrintWriter(System.out), sfm, diagnostics,
+                Arrays.asList("-proc:only"), null,
+                Arrays.asList(entity, nonEntity, generated8, generated9));
+        CanonicalModelProcessor modelProcessor = new CanonicalModelProcessor();
+        task.setProcessors(Collections.singleton(modelProcessor));
+        task.call();
+        
+        for ( Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
+            System.out.println(diagnostic);
+        }
+        Assert.assertTrue("Model file not generated", new File(srcOut, "org/Sample_.java").exists());
+    }
+
+    private static class TestFO extends SimpleJavaFileObject {
+        private final String text;
+
+        public TestFO(String name, String code) {
+            super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),
+                    Kind.SOURCE);
+            this.text = code;
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return text;
+        }
+    }
+
+    private static final String PXML = "<persistence xmlns=\"http://xmlns.jcp.org/xml/ns/persistence\"\n" + 
+            "  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + 
+            "  xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/persistence\n" + 
+            "    http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd\"\n" + 
+            "  version=\"2.2\">\n" + 
+            "     <persistence-unit name=\"sample-pu\" transaction-type=\"RESOURCE_LOCAL\">\n" + 
+            "          <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>\n" + 
+            "          <exclude-unlisted-classes>false</exclude-unlisted-classes>\n" + 
+            "          <properties>\n" + 
+            "          </properties>\n" + 
+            "     </persistence-unit>\n" + 
+            "</persistence>";
+    
+    private static void delete(File dir) throws IOException {
+        Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                Files.delete(file);
+                return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
+                Files.delete(dir);
+                return FileVisitResult.CONTINUE;
+            }
+        });
+    }
+
+}