Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

698
Vistas
Lanzar una excepción de CompletableFuture cuelga get() y join() en Java 17

Después de cambiar de Java 11 a Java 17 (OpenJDK instalado desde el repositorio de Ubuntu 20.04), el siguiente código no funciona:

 import java.util.Objects; import java.util.concurrent.CompletableFuture; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.lang3.exception.ExceptionUtils; public class TestClass { public static void main(String[] args) { CompletableFuture<String> streamFuture = CompletableFuture.supplyAsync(() -> { throw MyException.wrapIfNeeded(new Exception("MyException")); }); String result = null; try { result = streamFuture.get(); } catch (Exception e) { System.out.println("Exception: " + ExceptionUtils.getMessage(e)); } System.out.println("Result: " + Objects.toString(result)); } static class MyException extends RuntimeException { private static final long serialVersionUID = 3349188601484197015L; public MyException(Throwable cause) { super(cause == null ? null : cause.getMessage(), cause); } public static MyException wrapIfNeeded(Throwable e) { return e instanceof MyException ? (MyException) e : new MyException(e); } @Override public String toString() { return ReflectionToStringBuilder.toString(this); } } }

Hay un problema en streamFuture.get() : se cuelga infinitamente. Profundicé más y descubrí que en java.util.concurrent.ForkJoinPool hay un método unmanagedBlock(ManagedBlocker blocker) que parece

 /** ManagedBlock for external threads */ private static void unmanagedBlock(ManagedBlocker blocker) throws InterruptedException { if (blocker == null) throw new NullPointerException(); do {} while (!blocker.isReleasable() && !blocker.block()); }

y el programa se cuelga infinitamente en el bucle do-while.

EDITAR: descubrí que el problema se debe al método toString() agregado a mi clase de excepción personalizada. Por alguna razón, comenzó a ser un problema después de Java 11

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

El problema se debe a que ReflectionToStringBuilder.toString usa la API Java encapsulada.

Podemos probar algo como MyException.wrapIfNeeded(new NullPointerException("")).toString() Y veremos

Excepción en el subproceso "principal" java.lang.reflect.InaccessibleObjectException: no se puede hacer que el campo sea estático final largo java.lang.RuntimeException.serialVersionUID accesible: el módulo java.base no "abre java.lang" en el módulo sin nombre @ b4c966a

¿Por qué esta causa colgará infinitamente?

En el método CompletableFuture.AsyncSupply#run

 static final class AsyncSupply<T> extends ForkJoinTask<Void> implements Runnable, AsynchronousCompletionTask { ... public void run() { CompletableFuture<T> d; Supplier<? extends T> f; if ((d = dep) != null && (f = fn) != null) { dep = null; fn = null; if (d.result == null) { try { d.completeValue(f.get()); } catch (Throwable ex) { d.completeThrowable(ex); } } d.postComplete(); } }

Dado que se lanza MyException , d.completeThrowable(ex); se llama, dentro de este método, envolverá la excepción en CompletionException , que llamará al constructor de Throwable con MyException como cause .

 public Throwable(Throwable cause) { fillInStackTrace(); detailMessage = (cause==null ? null : cause.toString()); this.cause = cause; }

Cuando se llama a cause.toString() , arrojará la excepción mencionada al principio, por lo que d.completeThrowable(ex); no se ejecuta completamente y, por lo tanto, el programa se colgará para siempre.

over 4 years ago · Santiago Trujillo Denunciar

0

Descubrí que el problema se debe al método toString() agregado a mi clase de excepción personalizada. Por alguna razón (o para ser más precisos: ReflectionToStringBuilder.toString(this); ) comenzó a ser un problema después de Java 11.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda