processing / processing/processing4

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

Offen
#984 4 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug help wanted
Vorherrschende Sprache
Java
Sterne
494
Forks
183
Ø Merge
4 Std. 39 Min.
Gemergte PRs (30 T.)
3

Beschreibung

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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne in processing.core.PApplet beim im Stacktrace gezeigten nf-Aufruf und untersuche anschließend die zugehörigen nf- und nfc-Formatierungspfade sowie deren NumberFormat-Zustand. Führe die Thread-Reproduktion wiederholt mit nf(float, int, int), nf(int, int) und nfc(float, int) aus; abgeschlossen ist die Aufgabe, wenn die nebenläufige Ausführung nicht mehr die gemeldete NullPointerException oder den StackOverflow erzeugt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
java
Bereich
api
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.