Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

697
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda