New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ClassCastException in AbstractPollingEndpoint #3418
Comments
Well, having that
we cast a caught It looks like Let me know what do you think and we will proceed with the fix! |
Right but Something definitely odd. I do remember talking to Juergen a few years ago; there are some strange corner cases where this can happen (I seem to recall it had something to do with Constructors, but I don't remember the details). |
Found it - using Here's a discussion. It has been deprecated since Java 9 for this reason: * @deprecated This method propagates any exception thrown by the
* nullary constructor, including a checked exception. Use of
* this method effectively bypasses the compile-time exception
* checking that would otherwise be performed by the compiler.
* The {@link
* java.lang.reflect.Constructor#newInstance(java.lang.Object...)
* Constructor.newInstance} method avoids this problem by wrapping
* any exception thrown by the constructor in a (checked) {@link
* java.lang.reflect.InvocationTargetException}. |
Correct. That's why I suggest to use a We probably have just never seen this problem because we are mostly on Java 8 yet. |
I reproduced it quite easily; I don't see any such code in the framework. @toddlindner - if you want to track down the root cause (where the actual exception is thrown), you can add this advice to the poller: private ReceiveMessageAdvice errorTrapper() {
return new ReceiveMessageAdvice() {
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
return ReceiveMessageAdvice.super.invoke(invocation);
}
catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new IllegalStateException(e);
}
}
@Override
@Nullable
public Message<?> afterReceive(@Nullable Message<?> result, Object source) {
return result;
}
};
} This assumes SI 5.3 or later, for earlier versions (4.2 or later) you would have to extend Here's the complete test app: @SpringBootApplication
public class Sigh3418Application {
private static final Logger LOG = LoggerFactory.getLogger(Sigh3418Application.class);
public static void main(String[] args) {
SpringApplication.run(Sigh3418Application.class, args);
}
@Bean
public IntegrationFlow flow() {
return IntegrationFlows.from(new MyMS(), e -> e.poller(Pollers.fixedDelay(5000).advice(errorTrapper())))
.nullChannel();
}
private ReceiveMessageAdvice errorTrapper() {
return new ReceiveMessageAdvice() {
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
return ReceiveMessageAdvice.super.invoke(invocation);
}
catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new IllegalStateException(e);
}
}
@Override
@Nullable
public Message<?> afterReceive(@Nullable Message<?> result, Object source) {
return result;
}
};
}
}
class MyMS implements MessageSource<String> {
@Override
@Nullable
public Message<String> receive() {
try {
Foo.class.newInstance();
}
catch (InstantiationException | IllegalAccessException e) {
}
return null;
}
}
class Foo {
public Foo() throws IOException {
throw new IOException();
}
} |
?? It fails with Java8 the same way. |
Thanks guys. Wow good catch Juergen and Gary on the Class.newInstance() issue. I never would have thought that was possible. |
So, @garyrussell , I assign this to you because it looks like you are fully on board with the problem. Thanks |
Resolves spring-projects#3418 `Class.newInstance()` can propagate checked exceptions that are not declared. **cherry-pick/back-port to 5.3.x, 5.2.x, 4.3.x**
Resolves #3418 `Class.newInstance()` can propagate checked exceptions that are not declared. **cherry-pick/back-port to 5.3.x, 5.2.x, 4.3.x**
Resolves #3418 `Class.newInstance()` can propagate checked exceptions that are not declared. **cherry-pick/back-port to 5.3.x, 5.2.x, 4.3.x**
Resolves #3418 `Class.newInstance()` can propagate checked exceptions that are not declared. **cherry-pick/back-port to 5.3.x, 5.2.x, 4.3.x** # Conflicts: # spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractPollingEndpoint.java
Resolves #3418 `Class.newInstance()` can propagate checked exceptions that are not declared. **cherry-pick/back-port to 5.3.x, 5.2.x, 4.3.x**
Now that I am running the release I found the root cause of this. I had been using lombok @SneakyThrows on the accept() method of a FileListFilter, and it was throwing java.lang.reflect.UndeclaredThrowableException |
Spring Integration 5.3.2.RELEASE
I am seeing a
ClassCastException
during error handling inAbstractPollingEndpoint
. Using jdk15 so there is more detail on theClassCastException
.The thing is, looking at this line
spring-integration/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractPollingEndpoint.java
Line 417 in fb35a73
For the life of me, I can't understand how a non
RuntimeException
can make it here. In my case I am gettingjava.nio.file.NoSuchFileException
. Understand this is not an ideal bug report, but as a pure Java dev, I still cant figure out how a non-runtime exception can make it to line 417. ThereceiveMessage()
method above has no throws declared so the exception thrown must be aRuntimeException
, butjava.nio.file.NoSuchFileException
is not. The only thing I can think of would be some sort of lombok@SneakyThrows
somewhere but that would still create aUndeclaredThrowableException
around the inner exception.I am not trying to stop the exception (I assume a user had a file locked during polling or something similar), I just want to get a normal throw without a
ClassCastException
.This error only happens about once per day so it is difficult to reproduce. The app has about 10 pollers but they are all similar. Unfortunately I don't know which one is failing since there is no other information in the log or the stack trace regarding bean id.
The spring configuraiton xml is using this adapter
<int-file:inbound-channel-adapter>
The text was updated successfully, but these errors were encountered: