Fix potential issue when Message is not available but not needed
If an isolated function doesn't have Message in its classpath, we will never actually need to instantiate that class. This change makes sure we check first.
This commit is contained in:
@@ -90,10 +90,12 @@ public abstract class MessageUtils {
|
||||
return MessageBuilder.withPayload(message).build();
|
||||
}
|
||||
ClassLoader classLoader = ((Isolated) handler).getClassLoader();
|
||||
Class<?> type = ClassUtils.resolveClassName(Message.class.getName(), classLoader);
|
||||
Class<?> type = ClassUtils.isPresent(Message.class.getName(), classLoader)
|
||||
? ClassUtils.resolveClassName(Message.class.getName(), classLoader)
|
||||
: null;
|
||||
Object payload;
|
||||
Map<String, Object> headers;
|
||||
if (type.isAssignableFrom(message.getClass())) {
|
||||
if (type != null && type.isAssignableFrom(message.getClass())) {
|
||||
Method getPayload = ClassUtils.getMethod(type, "getPayload");
|
||||
Method getHeaders = ClassUtils.getMethod(type, "getHeaders");
|
||||
payload = ReflectionUtils.invokeMethod(getPayload, message);
|
||||
@@ -101,7 +103,8 @@ public abstract class MessageUtils {
|
||||
Map<String, Object> map = (Map<String, Object>) ReflectionUtils
|
||||
.invokeMethod(getHeaders, message);
|
||||
headers = map;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
payload = message;
|
||||
headers = Collections.emptyMap();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.function.stream.function;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
@@ -38,19 +39,40 @@ import reactor.core.publisher.Flux;
|
||||
*
|
||||
*/
|
||||
public class ClassLoaderUtils {
|
||||
|
||||
|
||||
@Test
|
||||
public void fluxIsShared() {
|
||||
Class<?> flux = ClassUtils.resolveClassName(Flux.class.getName(), createClassLoader());
|
||||
Class<?> flux = ClassUtils.resolveClassName(Flux.class.getName(),
|
||||
createClassLoader());
|
||||
assertThat(flux).isEqualTo(Flux.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void messageIsNotShared() {
|
||||
Class<?> flux = ClassUtils.resolveClassName(Message.class.getName(), createClassLoader());
|
||||
Class<?> flux = ClassUtils.resolveClassName(Message.class.getName(),
|
||||
createClassLoader());
|
||||
assertThat(flux).isNotEqualTo(Message.class);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void messageIsNotAvailable() {
|
||||
Class<?> flux = ClassUtils.resolveClassName(Message.class.getName(),
|
||||
createMinimalClassLoader());
|
||||
assertThat(flux).isNotEqualTo(Message.class);
|
||||
}
|
||||
|
||||
public static ClassLoader createMinimalClassLoader() {
|
||||
ClassLoader base = ClassLoaderUtils.class.getClassLoader();
|
||||
try {
|
||||
return new URLClassLoader(
|
||||
new URL[] { new File("target/test-classes").toURI().toURL() },
|
||||
base.getParent());
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static ClassLoader createClassLoader() {
|
||||
URL[] urls = findClassPath();
|
||||
if (urls.length == 1) {
|
||||
@@ -171,4 +193,5 @@ public class ClassLoaderUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -73,7 +73,18 @@ public class MessageUtilsTests {
|
||||
Object output = MessageUtils.unpack(function, "foo");
|
||||
assertThat(output).isInstanceOf(Message.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<String> message = (Message<String>)output;
|
||||
Message<String> message = (Message<String>) output;
|
||||
assertThat(message.getPayload()).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnpackIsolatedMessageNotAvailable() throws Exception {
|
||||
Object function = create(Uppercase.class,
|
||||
ClassLoaderUtils.createMinimalClassLoader());
|
||||
Object output = MessageUtils.unpack(function, "foo");
|
||||
assertThat(output).isInstanceOf(Message.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<String> message = (Message<String>) output;
|
||||
assertThat(message.getPayload()).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@@ -89,6 +100,10 @@ public class MessageUtilsTests {
|
||||
}
|
||||
|
||||
private Object create(Class<Uppercase> type) {
|
||||
return create(type, loader);
|
||||
}
|
||||
|
||||
private Object create(Class<Uppercase> type, ClassLoader loader) {
|
||||
return new IsolatedFunction<>((Function<?, ?>) BeanUtils
|
||||
.instantiate(ClassUtils.resolveClassName(type.getName(), loader)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user