processing / processing/processing4

nf/nfc do not seem to be threadsafe and throw NullPointerException

Abierto
#984 4 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

bug help wanted
Lenguaje dominante
Java
Estrellas
494
Forks
183
Merge medio
4 h 39 min
PR fusionados (30 d)
3

Descripción

Most appropriate sub-area of Processing 4?

Core/Environment/Rendering

Processing version

3 to current

Operating system

Linux

Steps to reproduce this

"1. Create a method calling nf(float, int, int), nf(int, int), nfc(float, int)

  1. Run this method within a thread thread("myFunction").

  2. Let it run for a longer time"

This is a little bit harder to reproduce and I only got it first with a complex project.

After a while you will end up with either a Stackoverflow or NullPointerException like this.

java.lang.NullPointerException: Cannot assign field "fastPathContainer" because "this.fastPathData" is null
    at java.base/java.text.DecimalFormat.resetFastPathData(DecimalFormat.java:1157)
    at java.base/java.text.DecimalFormat.checkAndSetFastPathStatus(DecimalFormat.java:1081)
    at java.base/java.text.DecimalFormat.fastFormat(DecimalFormat.java:1659)
    at java.base/java.text.NumberFormat.format(NumberFormat.java:327)
    at processing.core.PApplet.nf(PApplet.java:10108)
    at core3.app.gui.GUIInfo.pre(GUIInfo.java:413)
    at jdk.internal.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:569)
    at processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1436)
    at processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1429)
    at processing.core.PApplet.handleMethods(PApplet.java:1628)
    at processing.core.PApplet.handleDraw(PApplet.java:2473)
    at processing.opengl.PSurfaceJOGL$DrawListener.display(PSurfaceJOGL.java:866)
    at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
    at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
    at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:443)
    at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
    at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
    at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:759)
    at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:81)
    at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:452)
    at com.jogamp.opengl.util.FPSAnimator$MainTask.run(FPSAnimator.java:178)
    at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
    at java.base/java.util.TimerThread.run(Timer.java:516) 
snippet
Additional context

Doing a little bit research, the NumberFormat in nf/nfc seems not to be thread safe. General consent on this seems to be to use a ThreadLocal. So modifying PApplet like this, seems to fix it.


private static final ThreadLocal<NumberFormat> threadLocalIntNf = ThreadLocal.withInitial(() -> {
  NumberFormat nf = NumberFormat.getInstance();
  nf.setGroupingUsed(false); // no commas
  nf.setMinimumFractionDigits(0);
  nf.setMaximumFractionDigits(0);
  return nf;
});


  static public String nf(float num, int left, int right) {
//    if ((float_nf != null) &&
//        (float_nf_left == left) &&
//        (float_nf_right == right) &&
//        !float_nf_commas) {
//      return float_nf.format(num);
//    }

    float_nf = threadLocalIntNf.get();
    float_nf.setGroupingUsed(false);
    float_nf_commas = false;

    float_nf.setMinimumIntegerDigits(left);
    float_nf.setMinimumFractionDigits(right);
    float_nf.setMaximumFractionDigits(right);

    return float_nf.format(num);
  }
Would you like to work on the issue?

I can provide my fix, but it needs some optimisation/cleanup.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza en processing.core.PApplet, en la llamada a nf mostrada en el stack trace; después inspecciona las rutas de formateo relacionadas de nf y nfc y su estado de NumberFormat. Ejecuta repetidamente la reproducción con hilos usando nf(float, int, int), nf(int, int) y nfc(float, int); se considera terminado cuando la ejecución concurrente ya no produce la NullPointerException ni el StackOverflow indicados.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
java
Área
api
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
45/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.