Exception with "Discarding connection." message

Today our build started to throw strange exceptions during gradle build (this one never happened before). If I run build with debug messaging turned on I see lots of following messages:

TRACE - 28 Feb 02012 12:48:44.348 - Outgoing Connection [3443153e-30fc-4a50-b9c4-f430632aa45c port:53113, addresses:[/0:0:0:0:0:0:0:1%1, /127.0.0.1]]:0 worker - org.hibernate.type.descriptor.sql.BasicBinder | binding parameter [1] as [BOOLEAN] - true TRACE - 28 Feb 02012 12:48:44.348 - Outgoing Connection [3443153e-30fc-4a50-b9c4-f430632aa45c port:53113, addresses:[/0:0:0:0:0:0:0:1%1, /127.0.0.1]]:0 worker - org.hibernate.type.descriptor.sql.BasicBinder | binding parameter [2] as [VARCHAR] - TRACE - 28 Feb 02012 12:48:44.349 - Outgoing Connection [3443153e-30fc-4a50-b9c4-f430632aa45c port:53113, addresses:[/0:0:0:0:0:0:0:1%1, /127.0.0.1]]:0 worker - org.hibernate.type.EnumType | Binding {0} to parameter: 3

Which eventually leads to following exception:

Could not receive message from connection. Discarding connection. org.gradle.messaging.remote.internal.MessageIOException: Could not read message from ‘/0:0:0:0:0:0:0:1:59280’.

at org.gradle.messaging.remote.internal.inet.SocketConnection.receive(SocketConnection.java:81)

at org.gradle.messaging.remote.internal.DelegatingConnection.receive(DelegatingConnection.java:31)

at org.gradle.messaging.remote.internal.MessageHub$EndOfStreamConnection.receive(MessageHub.java:210)

at org.gradle.messaging.remote.internal.MessageHub$EndOfStreamConnection.receive(MessageHub.java:195)

at org.gradle.messaging.remote.internal.AsyncConnectionAdapter$ConnectionReceive.receive(AsyncConnectionAdapter.java:77)

at org.gradle.messaging.dispatch.AsyncReceive.receiveMessages(AsyncReceive.java:142)

at org.gradle.messaging.dispatch.AsyncReceive.access$000(AsyncReceive.java:36)

at org.gradle.messaging.dispatch.AsyncReceive$1.run(AsyncReceive.java:88)

at org.gradle.messaging.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

at java.lang.Thread.run(Thread.java:662) Caused by: java.lang.ClassCastException: cannot assign instance of org.gradle.messaging.remote.internal.PlaceholderException to field java.sql.SQLException.next of type java.sql.SQLException in instance of java.sql.BatchUpdateException

at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2039)

at java.io.ObjectStreamClass.setObjFieldValues(ObjectStreamClass.java:1212)

at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1952)

at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)

at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)

at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)

at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)

at org.gradle.messaging.remote.internal.Message$ExceptionPlaceholder.read(Message.java:93)

at org.gradle.messaging.remote.internal.Message$ExceptionPlaceholder.getCause(Message.java:121)

at org.gradle.messaging.remote.internal.Message$ExceptionPlaceholder.read(Message.java:80)

at org.gradle.messaging.remote.internal.Message$ExceptionReplacingObjectInputStream.resolveObject(Message.java:158)

at java.io.ObjectInputStream.checkResolve(ObjectInputStream.java:1376)

at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)

at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666)

at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322)

at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)

at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)

at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)

at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)

at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)

at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)

at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)

at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)

at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)

at org.gradle.messaging.remote.internal.Message.receive(Message.java:38)

at org.gradle.messaging.remote.internal.DefaultMessageSerializer.read(DefaultMessageSerializer.java:31)

at org.gradle.messaging.remote.internal.inet.SocketConnection.receive(SocketConnection.java:76)

… 11 more

Anyone ever happend to have the same issue ?

It looks like a test is throwing a ‘java.sql.BatchUpdateException’, and the test JVM fails to inform the Gradle JVM of that event (tests run in a separate JVM). This looks like a Gradle bug. Until this gets fixed, your best chance is to prevent tests from throwing that particular exception, for example by wrapping affected tests in a try-catch and throwing a RuntimeException instead. You can copy over message and stack trace, but do not chain the original exception.

I’ve created GRADLE-2131 for this.

I’m having the same issue13:02:29.643 [ERROR] [org.gradle.messaging.remote.internal.MessageHub$EndOfStreamConnection] Could not receive message from connection. Discarding connection. org.gradle.messaging.remote.internal.MessageIOException: Could not read message from ‘/0:0:0:0:0:0:0:1%0:53225’.

at org.gradle.messaging.remote.internal.inet.SocketConnection.receive(SocketConnection.java:83)

at org.gradle.messaging.remote.internal.DelegatingConnection.receive(DelegatingConnection.java:31)

at org.gradle.messaging.remote.internal.MessageHub$EndOfStreamConnection.receive(MessageHub.java:210)

at org.gradle.messaging.remote.internal.MessageHub$EndOfStreamConnection.receive(MessageHub.java:195)

at org.gradle.messaging.remote.internal.AsyncConnectionAdapter$ConnectionReceive.receive(AsyncConnectionAdapter.java:77)

at org.gradle.messaging.dispatch.AsyncReceive.receiveMessages(AsyncReceive.java:142)

at org.gradle.messaging.dispatch.AsyncReceive.access$000(AsyncReceive.java:36)

at org.gradle.messaging.dispatch.AsyncReceive$1.run(AsyncReceive.java:88)

at org.gradle.messaging.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

at java.lang.Thread.run(Thread.java:680) Caused by: java.lang.ClassCastException: cannot assign instance of org.gradle.messaging.remote.internal.PlaceholderException to field java.sql.SQLException.next of type java.sql.SQLException in instance of java.sql.BatchUpdateException

Let me know if you need help replicating.

I think the relevant bit is:

cannot assign instance of org.gradle.messaging.remote.internal.PlaceholderException to field java.sql.SQLException.next of type java.sql.SQLException in instance of java.sql.BatchUpdateException

The PlaceHolderException is used when an exception cannot be serialized or deserialized. In this case an instance of BatchUpdateException is attempting to be deserialized, which is a subclass of SqlException. SqlException has a volatile field called ‘next’ which is also of type SqlException. It appears the messaging framework in Gradle did not want to serialize the volatile field, so instead used a PlaceHolderException, but it left the type of the ‘next’ field as SqlException when it is in fact now ‘PlaceHolderException’. I’ll keep digging…

I have seen a similar problem and it turned out that something called System.exit() which probably killed the test executing VM. This is probably not directly related to the issue, but might help others that find this thread.

Gosh, any idea how to work around this? This is not related to system exit, it’s just the serializer between processes trying to send an object that is not serializable. Is there any way to prevent gradle from spawning another process and just pass a handle to the object instead?

It’s been a while since this was first reported, and I still get gradle to freeze up every time an integration test throws a SQLException…

Usually, Gradle will replace unserializable exceptions with a serializable ‘PlaceHolderException’. However, there are some cases where this doesn’t work correctly. Until the linked issue is fixed, your best bet is to make sure that problematic exceptions like ‘SQLException’ aren’t thrown from test methods, for example by writing a little JUnit ‘@Rule’. I’m sorry that I don’t have a better solution.