Merge branch '4.1.x' into 4.2.x
This commit is contained in:
1
pom.xml
1
pom.xml
@@ -66,7 +66,6 @@
|
||||
<xerces.version>2.12.2</xerces.version>
|
||||
<jacoco-maven-plugin.version>0.8.8</jacoco-maven-plugin.version>
|
||||
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
|
||||
<InMemoryJavaCompiler.version>1.3.0</InMemoryJavaCompiler.version>
|
||||
|
||||
<contract.kotlin.version>1.8.22</contract.kotlin.version>
|
||||
<commons-beanutils.version>1.9.4</commons-beanutils.version>
|
||||
|
||||
@@ -247,12 +247,6 @@
|
||||
<artifactId>spring-boot-starter-jersey</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.mdkt.compiler</groupId>
|
||||
<artifactId>InMemoryJavaCompiler</artifactId>
|
||||
<version>${InMemoryJavaCompiler.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>jetty-ee10-servlet</artifactId>
|
||||
<groupId>org.eclipse.jetty.ee10</groupId>
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.cloud.contract.verifier.builder
|
||||
|
||||
import org.junit.Rule
|
||||
import org.mdkt.compiler.CompilationException
|
||||
import spock.lang.Issue
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Specification
|
||||
@@ -238,7 +237,7 @@ class MockMvcMethodBodyBuilderWithMatchersSpec extends Specification implements
|
||||
try {
|
||||
SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test)
|
||||
}
|
||||
catch (CompilationException classFormatError) {
|
||||
catch (Exception classFormatError) {
|
||||
String output = classFormatError.message
|
||||
assert output.contains('cannot find symbol')
|
||||
assert output.contains('assertThatValueIsANumber')
|
||||
|
||||
@@ -19,6 +19,16 @@ package org.springframework.cloud.contract.verifier.util
|
||||
import java.lang.reflect.Method
|
||||
|
||||
import javax.inject.Inject
|
||||
import javax.tools.Diagnostic
|
||||
import javax.tools.DiagnosticCollector
|
||||
import javax.tools.FileObject
|
||||
import javax.tools.ForwardingJavaFileManager
|
||||
import javax.tools.JavaCompiler
|
||||
import javax.tools.JavaFileManager
|
||||
import javax.tools.JavaFileObject
|
||||
import javax.tools.SimpleJavaFileObject
|
||||
import javax.tools.StandardJavaFileManager
|
||||
import javax.tools.ToolProvider
|
||||
import javax.ws.rs.client.Entity
|
||||
import javax.ws.rs.client.WebTarget
|
||||
import javax.ws.rs.core.Response
|
||||
@@ -35,7 +45,6 @@ import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer
|
||||
import org.codehaus.groovy.control.customizers.ImportCustomizer
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mdkt.compiler.InMemoryJavaCompiler
|
||||
import org.w3c.dom.Document
|
||||
import org.xml.sax.InputSource
|
||||
|
||||
@@ -46,6 +55,7 @@ import org.springframework.cloud.contract.verifier.messaging.internal.ContractVe
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper
|
||||
import org.springframework.cloud.contract.verifier.messaging.util.ContractVerifierMessagingUtil
|
||||
import org.springframework.util.ReflectionUtils
|
||||
|
||||
/**
|
||||
* checking the syntax of produced scripts
|
||||
*/
|
||||
@@ -110,8 +120,7 @@ private void test(String test) {
|
||||
try {
|
||||
if (builderName.toLowerCase().contains("spock")) {
|
||||
tryToCompileGroovy(builderName, test)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
tryToCompileJava(builderName, test)
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
@@ -125,8 +134,7 @@ private void test(String test) {
|
||||
if (builderName.toLowerCase().contains("spock")) {
|
||||
Script script = tryToCompileGroovy(builderName, test)
|
||||
script.invokeMethod("validate_method()", null)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Class clazz = tryToCompileJava(builderName, test)
|
||||
Method method = ReflectionUtils.findMethod(clazz, "validate_method")
|
||||
method.invoke(clazz.newInstance())
|
||||
@@ -141,8 +149,7 @@ private void test(String test) {
|
||||
static void tryToCompileWithoutCompileStatic(String builderName, String test) {
|
||||
if (builderName.toLowerCase().contains("spock")) {
|
||||
tryToCompileGroovy(builderName, test, false)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
tryToCompileJava(builderName, test)
|
||||
}
|
||||
}
|
||||
@@ -162,7 +169,7 @@ private void test(String test) {
|
||||
|
||||
private static String updatedTest(String test, String className) {
|
||||
test.replaceAll("class FooTest", "class " + className)
|
||||
.replaceAll("import javax.ws.rs.core.Response", "import javax.ws.rs.core.Response; import javax.ws.rs.client.WebTarget;")
|
||||
.replaceAll("import javax.ws.rs.core.Response", "import javax.ws.rs.core.Response; import javax.ws.rs.client.WebTarget;")
|
||||
}
|
||||
|
||||
private static GString getStaticImports(String builderName) {
|
||||
@@ -176,15 +183,43 @@ private void test(String test) {
|
||||
String className = className(test)
|
||||
String fqnClassName = "com.example.${className}"
|
||||
test = test.replaceAll("class FooTest", "class " + className)
|
||||
.replaceAll("import javax.ws.rs.core.Response", "import javax.ws.rs.core.Response; import javax.ws.rs.client.WebTarget;")
|
||||
.replaceAll("import javax.ws.rs.core.Response", "import javax.ws.rs.core.Response; import javax.ws.rs.client.WebTarget;")
|
||||
return compileJava(fqnClassName, test)
|
||||
|
||||
}
|
||||
|
||||
private static Class<?> compileJava(String fqnClassName, String test) {
|
||||
return InMemoryJavaCompiler.newInstance()
|
||||
.ignoreWarnings()
|
||||
.compile(fqnClassName, test)
|
||||
@CompileStatic
|
||||
private static Class<?> compileJava(String fqnClassName, String sourceCode) {
|
||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler()
|
||||
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>()
|
||||
InMemoryClassLoader classLoader = new InMemoryClassLoader()
|
||||
StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(diagnostics, null, null)
|
||||
JavaFileManager fileManager = new InMemoryFileManager(standardFileManager, classLoader)
|
||||
JavaFileObject javaFile = new InMemorySourceFile(fqnClassName, sourceCode)
|
||||
JavaCompiler.CompilationTask task = compiler.getTask(
|
||||
new StringWriter(),
|
||||
fileManager,
|
||||
diagnostics,
|
||||
null,
|
||||
null,
|
||||
Collections.singletonList(javaFile)
|
||||
)
|
||||
|
||||
boolean success = task.call()
|
||||
if (!success) {
|
||||
StringBuilder errorMsg = new StringBuilder("Compilation failed:")
|
||||
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
|
||||
errorMsg.append("\nLine ").append(diagnostic.getLineNumber())
|
||||
.append(": ").append(diagnostic.getMessage(null))
|
||||
}
|
||||
throw new IllegalStateException(errorMsg.toString())
|
||||
}
|
||||
|
||||
try {
|
||||
return classLoader.loadClass(fqnClassName)
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException("Failed to load compiled class", e)
|
||||
}
|
||||
}
|
||||
|
||||
private static String className(String test) {
|
||||
@@ -210,4 +245,81 @@ private void test(String test) {
|
||||
return true
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
private static class InMemorySourceFile extends SimpleJavaFileObject {
|
||||
private final String sourceCode
|
||||
|
||||
InMemorySourceFile(String className, String sourceCode) {
|
||||
super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension),
|
||||
Kind.SOURCE)
|
||||
this.sourceCode = sourceCode
|
||||
}
|
||||
|
||||
@Override
|
||||
CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||
return sourceCode
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
private static class InMemoryClassLoader extends ClassLoader {
|
||||
private final Map<String, byte[]> classData = new HashMap<>()
|
||||
|
||||
void addClass(String name, byte[] data) {
|
||||
classData.put(name, data)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
byte[] data = classData.get(name)
|
||||
if (data == null) {
|
||||
throw new ClassNotFoundException(name)
|
||||
}
|
||||
return defineClass(name, data, 0, data.length)
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
private static class InMemoryFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
|
||||
private final InMemoryClassLoader classLoader
|
||||
|
||||
InMemoryFileManager(StandardJavaFileManager fileManager, InMemoryClassLoader classLoader) {
|
||||
super(fileManager)
|
||||
this.classLoader = classLoader
|
||||
}
|
||||
|
||||
@Override
|
||||
JavaFileObject getJavaFileForOutput(Location location,
|
||||
String className,
|
||||
JavaFileObject.Kind kind,
|
||||
FileObject sibling) {
|
||||
return new InMemoryClassFile(className, classLoader)
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
private static class InMemoryClassFile extends SimpleJavaFileObject {
|
||||
private final String className
|
||||
private final InMemoryClassLoader classLoader
|
||||
private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
|
||||
|
||||
InMemoryClassFile(String className, InMemoryClassLoader classLoader) {
|
||||
super(URI.create("byte:///" + className.replace('.', '/') + Kind.CLASS.extension),
|
||||
Kind.CLASS)
|
||||
this.className = className
|
||||
this.classLoader = classLoader
|
||||
}
|
||||
|
||||
@Override
|
||||
OutputStream openOutputStream() {
|
||||
outputStream.reset()
|
||||
return new FilterOutputStream(outputStream) {
|
||||
@Override
|
||||
void close() throws IOException {
|
||||
super.close()
|
||||
classLoader.addClass(className, outputStream.toByteArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user