Skip to content
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 ReactiveAbstractSelectionQuery #1682

Closed
oleg-alexeyev opened this issue Jun 26, 2023 · 7 comments
Closed

ClassCastException in ReactiveAbstractSelectionQuery #1682

oleg-alexeyev opened this issue Jun 26, 2023 · 7 comments
Assignees

Comments

@oleg-alexeyev
Copy link

We're observing the following exception:

java.lang.ClassCastException: class java.lang.IllegalAccessError cannot be cast to class java.lang.RuntimeException (java.lang.IllegalAccessError and java.lang.RuntimeException are in module java.base of loader 'bootstrap')
13:13:43     at org.hibernate.reactive.query.spi.ReactiveAbstractSelectionQuery.convertException(ReactiveAbstractSelectionQuery.java:193)
13:13:43     at java.base/java.util.concurrent.CompletableFuture.uniExceptionally(CompletableFuture.java:990)
13:13:43     at java.base/java.util.concurrent.CompletableFuture$UniExceptionally.tryFire(CompletableFuture.java:974)
13:13:43     at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
13:13:43     at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
13:13:43     at org.hibernate.reactive.util.async.impl.AsyncTrampoline$TrampolineInternal.unroll(AsyncTrampoline.java:131)
13:13:43     at org.hibernate.reactive.util.async.impl.AsyncTrampoline$TrampolineInternal.lambda$unroll$0(AsyncTrampoline.java:126)
13:13:43     at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
13:13:43     at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
13:13:43     at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
13:13:43     at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
13:13:43     at io.vertx.core.Future.lambda$toCompletionStage$3(Future.java:536)
13:13:43     at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
13:13:43     at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
13:13:43     at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
13:13:43     at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
13:13:43     at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:88)
13:13:43     at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:32)
13:13:43     at io.vertx.core.Promise.complete(Promise.java:66)
13:13:43     at io.vertx.core.Promise.handle(Promise.java:51)
13:13:43     at io.vertx.core.Promise.handle(Promise.java:29)
13:13:43     at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
13:13:43     at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
13:13:43     at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
13:13:43     at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
13:13:43     at io.vertx.core.impl.future.PromiseImpl.onSuccess(PromiseImpl.java:49)
13:13:43     at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:41)
13:13:43     at io.vertx.sqlclient.impl.TransactionImpl.lambda$wrap$0(TransactionImpl.java:72)
13:13:43     at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
13:13:43     at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
13:13:43     at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
13:13:43     at io.vertx.core.impl.future.Transformation$1.onSuccess(Transformation.java:63)
13:13:43     at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
13:13:43     at io.vertx.core.impl.future.FutureImpl.addListener(FutureImpl.java:196)
13:13:43     at io.vertx.core.impl.future.PromiseImpl.addListener(PromiseImpl.java:23)
13:13:43     at io.vertx.core.impl.future.Transformation.onSuccess(Transformation.java:44)
13:13:43     at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
13:13:43     at io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:86)
13:13:43     at io.vertx.core.impl.DuplicatedContext.execute(DuplicatedContext.java:163)
13:13:43     at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:51)
13:13:43     at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
13:13:43     at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
13:13:43     at io.vertx.core.impl.future.PromiseImpl.onSuccess(PromiseImpl.java:49)
13:13:43     at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:41)
13:13:43     at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:23)
13:13:43     at io.vertx.sqlclient.impl.command.CommandResponse.fire(CommandResponse.java:46)
13:13:43     at io.vertx.sqlclient.impl.SocketConnectionBase.handleMessage(SocketConnectionBase.java:325)
13:13:43     at io.vertx.pgclient.impl.PgSocketConnection.handleMessage(PgSocketConnection.java:118)
13:13:43     at io.vertx.sqlclient.impl.SocketConnectionBase.lambda$init$0(SocketConnectionBase.java:138)
13:13:43     at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:55)
13:13:43     at io.vertx.core.impl.ContextBase.emit(ContextBase.java:239)
13:13:43     at io.vertx.core.net.impl.NetSocketImpl.handleMessage(NetSocketImpl.java:378)
13:13:43     at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:158)
13:13:43     at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:153)
13:13:43     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
13:13:43     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
13:13:43     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
13:13:43     at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
13:13:43     at io.vertx.pgclient.impl.codec.PgEncoder.lambda$write$0(PgEncoder.java:100)
13:13:43     at io.vertx.pgclient.impl.codec.PgCommandCodec.handleReadyForQuery(PgCommandCodec.java:139)
13:13:43     at io.vertx.pgclient.impl.codec.PgDecoder.decodeReadyForQuery(PgDecoder.java:237)
13:13:43     at io.vertx.pgclient.impl.codec.PgDecoder.channelRead(PgDecoder.java:96)
13:13:43     at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
13:13:43     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
13:13:43     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
13:13:43     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
13:13:43     at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
13:13:43     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
13:13:43     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
13:13:43     at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
13:13:43     at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
13:13:43     at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
13:13:43     at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
13:13:43     at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
13:13:43     at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
13:13:43     at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
13:13:43     at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
13:13:43     at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
13:13:43     at java.base/java.lang.Thread.run(Thread.java:831)

Unfortunately it's not clear how to reproduce this. But it's evident that the following code doesn't account for java.lang.Error subclasses:

	private R convertException(Throwable t) {
		if ( t instanceof CompletionException ) {
			t = t.getCause();
		}
		if ( t instanceof HibernateException ) {
			throw getSession().getExceptionConverter().convert( (HibernateException) t, getLockOptions() );
		}
		throw getSession().getExceptionConverter().convert( (RuntimeException) t, getLockOptions() );
	}
@oleg-alexeyev
Copy link
Author

oleg-alexeyev commented Jul 4, 2023

Here is the error message we've got from the IllegalAccessError:

'java.lang.Object org.hibernate.query.spi.AbstractSelectionQuery.uniqueElement(java.util.List)'
(org.hibernate.reactive.query.sqm.iternal.ReactiveQuerySqmImpl$$Lambda$3071/0x000000080228f980 and
org.hibernate.query.spi.AbstractSelectionQuery are in unnamed module of loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @664d4ee1)```

We get this exception when building the project using Maven/JDK 17 running on TeamCity, but not when running locally.

Any clue what can be the cause of this?

@DavideD
Copy link
Member

DavideD commented Jul 4, 2023

I'm not sure Hibernate Reactive should deal with these kind of error.
An IllegalAccessError means that some class is trying to access a field that's not reachable.
It might happen when something changes at runtime.

I'm not familiar with TeamCity, is it possible that some dependencies in your project have not been updated?
I don't know how to recreate the issue

@oleg-alexeyev
Copy link
Author

Thanks, I checked build with local maven repo cleaned. Unfortunately, the situation is the same.

Of course, it's hard to say how to repro and fix the IllegalAccessError. On the other hand, this issue is mostly about fixing the ClassCastException, and it seems to be quite easy - since Errors are not subclasses of RuntimeException, and ExceptionConverter doesn't have convert(Throwable,...) method, they could be wrapped into a RuntimeException, e.g.:

if ( t instanceof RuntimeException ) {
    throw getSession().getExceptionConverter().convert( (RuntimeException) t, getLockOptions() );
}
throw getSession().getExceptionConverter().convert( new RuntimeException(t), getLockOptions() );

Even better, of course, would be to refactor ExceptionConverter to support Throwable, but that of course might be a bigger task.

@DavideD
Copy link
Member

DavideD commented Jul 5, 2023

@oleg-alexeyev Would you like to send a fix for this issue? I think you are right that we shouldn't have a ClassCastException

This solution seems fine to me:

if ( t instanceof RuntimeException ) {
    throw getSession().getExceptionConverter().convert( (RuntimeException) t, getLockOptions() );
}
throw getSession().getExceptionConverter().convert( new RuntimeException(t), getLockOptions() );

@oleg-alexeyev
Copy link
Author

OK, I'll do.

gavinking added a commit to gavinking/hibernate-reactive that referenced this issue Jul 11, 2023
@gavinking
Copy link
Member

@oleg-alexeyev because we want to do a release today, I have fixed the problem in #1704.

@gavinking
Copy link
Member

Fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants