diff --git a/spring-cloud-function-deployer-new/src/it/bootjarnostart/pom.xml b/spring-cloud-function-deployer-new/src/it/bootjarnostart/pom.xml new file mode 100644 index 000000000..cc4a82d04 --- /dev/null +++ b/spring-cloud-function-deployer-new/src/it/bootjarnostart/pom.xml @@ -0,0 +1,67 @@ + + + 4.0.0 + + function.example + bootjarnostart + 0.0.1.BUILD-SNAPSHOT + jar + + + org.springframework.boot + spring-boot-starter-parent + 2.2.0.BUILD-SNAPSHOT + + + + + 1.8 + 3.0.0.BUILD-SNAPSHOT + 1.0.17.RELEASE + + + + + org.springframework.boot + spring-boot-starter + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + NONE + exec + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack + package + + unpack + + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + exec + + + + + + + + + diff --git a/spring-cloud-function-deployer-new/src/it/bootjarnostart/src/main/java/function/example/UpperCaseFunction.java b/spring-cloud-function-deployer-new/src/it/bootjarnostart/src/main/java/function/example/UpperCaseFunction.java new file mode 100644 index 000000000..859a54a58 --- /dev/null +++ b/spring-cloud-function-deployer-new/src/it/bootjarnostart/src/main/java/function/example/UpperCaseFunction.java @@ -0,0 +1,13 @@ +package function.example; + +import java.util.function.Function; + +public class UpperCaseFunction implements Function { + + @Override + public String apply(String value) { + System.out.println("Uppercasing " + value); + return value.toUpperCase(); + } + +} diff --git a/spring-cloud-function-deployer-new/src/main/java/org/springframework/cloud/function/deployer/ExternalFunctionJarLauncher.java b/spring-cloud-function-deployer-new/src/main/java/org/springframework/cloud/function/deployer/ExternalFunctionJarLauncher.java index d05d86936..40253b62c 100644 --- a/spring-cloud-function-deployer-new/src/main/java/org/springframework/cloud/function/deployer/ExternalFunctionJarLauncher.java +++ b/spring-cloud-function-deployer-new/src/main/java/org/springframework/cloud/function/deployer/ExternalFunctionJarLauncher.java @@ -154,23 +154,29 @@ class ExternalFunctionJarLauncher extends JarLauncher { return functionRegistration; } + protected boolean isBootApplicationWithMain() throws Exception { + return StringUtils.hasText(this.archive.getManifest().getMainAttributes().getValue("Start-Class")); + } + private void launch(ApplicationContext deployerContext, String[] args) throws Exception { JarFile.registerUrlProtocolHandler(); Thread.currentThread().setContextClassLoader(createClassLoader(getClassPathArchives())); evalContext.setTypeLocator(new StandardTypeLocator(Thread.currentThread().getContextClassLoader())); - String mainClassName = getMainClass(); - Class mainClass = Thread.currentThread().getContextClassLoader().loadClass(mainClassName); + if (this.isBootApplicationWithMain()) { + String mainClassName = getMainClass(); + Class mainClass = Thread.currentThread().getContextClassLoader().loadClass(mainClassName); - Class bootAppClass = Thread.currentThread().getContextClassLoader() - .loadClass(SpringApplication.class.getName()); - Method runMethod = bootAppClass.getDeclaredMethod("run", Class.class, String[].class); - Object applicationContext = runMethod.invoke(null, mainClass, (Object) args); - if (logger.isInfoEnabled()) { - logger.info("Application context for archive '" + archive.getUrl() + "' is created."); + Class bootAppClass = Thread.currentThread().getContextClassLoader() + .loadClass(SpringApplication.class.getName()); + Method runMethod = bootAppClass.getDeclaredMethod("run", Class.class, String[].class); + Object applicationContext = runMethod.invoke(null, mainClass, (Object) args); + if (logger.isInfoEnabled()) { + logger.info("Application context for archive '" + archive.getUrl() + "' is created."); + } + evalContext.setVariable("context", applicationContext); + setBeanFactory(applicationContext); } - evalContext.setVariable("context", applicationContext); - setBeanFactory(applicationContext); } private void setBeanFactory(Object applicationContext) throws Exception { @@ -190,13 +196,15 @@ class ExternalFunctionJarLauncher extends JarLauncher { @SuppressWarnings("unchecked") private Map discoverFunctions() throws Exception { Map allFunctions = new HashMap(); - Expression parsed = new SpelExpressionParser() - .parseExpression("#context.getBeansOfType(T(java.util.function.Function))"); - allFunctions.putAll((Map) parsed.getValue(evalContext)); - parsed = new SpelExpressionParser().parseExpression("#context.getBeansOfType(T(java.util.function.Supplier))"); - allFunctions.putAll((Map) parsed.getValue(evalContext)); - parsed = new SpelExpressionParser().parseExpression("#context.getBeansOfType(T(java.util.function.Consumer))"); - allFunctions.putAll((Map) parsed.getValue(evalContext)); + if (evalContext.lookupVariable("context") != null) { // no start0class uber jars + Expression parsed = new SpelExpressionParser() + .parseExpression("#context.getBeansOfType(T(java.util.function.Function))"); + allFunctions.putAll((Map) parsed.getValue(evalContext)); + parsed = new SpelExpressionParser().parseExpression("#context.getBeansOfType(T(java.util.function.Supplier))"); + allFunctions.putAll((Map) parsed.getValue(evalContext)); + parsed = new SpelExpressionParser().parseExpression("#context.getBeansOfType(T(java.util.function.Consumer))"); + allFunctions.putAll((Map) parsed.getValue(evalContext)); + } return allFunctions; } } diff --git a/spring-cloud-function-deployer-new/src/test/java/org/springframework/cloud/function/deployer/ApplicationContainerTests.java b/spring-cloud-function-deployer-new/src/test/java/org/springframework/cloud/function/deployer/ApplicationContainerTests.java index bff4eb402..f482fcba2 100644 --- a/spring-cloud-function-deployer-new/src/test/java/org/springframework/cloud/function/deployer/ApplicationContainerTests.java +++ b/spring-cloud-function-deployer-new/src/test/java/org/springframework/cloud/function/deployer/ApplicationContainerTests.java @@ -46,6 +46,18 @@ public class ApplicationContainerTests { assertThat(invokerByClass.uppercaseSimple("stacy")).isEqualTo("STACY"); } + @Test + public void testCustomApplicationContainerWithBootJarNoStartClass() throws Exception { + String[] args = new String[] {"--spring.cloud.function.location=target/it/bootjarnostart/target/bootjarnostart-0.0.1.BUILD-SNAPSHOT-exec.jar", + "--spring.cloud.function.function-class=function.example.UpperCaseFunction"}; + + JavaInvoker invokerByClass = + FunctionDeployerBootstrap.instance(args).run(JavaInvoker.class, args); + + assertThat(invokerByClass.uppercaseSimple("bob")).isEqualTo("BOB"); + assertThat(invokerByClass.uppercaseSimple("stacy")).isEqualTo("STACY"); + } + @Test public void testCustomApplicationContainerWithBootAppSimpleTypes() throws Exception {