#15535 closed defect (fixed)
Freeze on Java 9 when you attempt to move node along a line using Extrusion tool
Reported by: | andygol | Owned by: | team |
---|---|---|---|
Priority: | critical | Milestone: | 17.11 |
Component: | Core | Version: | tested |
Keywords: | extrusion freezing java9 javabug | Cc: | ris, bastiK, michael2402 |
Description (last modified by )
I faced this bug in the latest (13097svn) and tested (13053) JOSM version on MacOS v10.13.1
$java --version java 9.0.1 Java(TM) SE Runtime Environment (build 9.0.1+11) Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
How to reproduce:
- Create a line or closed line (or use existing one)
- Make a try to move a node along the ways using
Ctrl
key (⌃
+⌥
- combination on my Mac)(https://josm.openstreetmap.de/wiki/Help/Action/Extrude#MoveanodealongadjacentsegmentCtrl) - JOSM is freezing and don't respond to any actions
Attachments (0)
Change History (34)
comment:1 by , 7 years ago
Summary: | JOSM is freezing when you attempt to move node using Extrusion tool → JOSM is freezing when you attempt to move node along a line using Extrusion tool |
---|
comment:2 by , 7 years ago
Description: | modified (diff) |
---|
comment:3 by , 7 years ago
comment:4 by , 7 years ago
Owner: | changed from | to
---|---|
Status: | new → needinfo |
comment:5 by , 7 years ago
It looks like JOSM with Java 9.0 doesn't work well on MacOS.
I've asked other guys to confirm this issue on MacOS with java8 update 141
and they could not reproduce it.
I will try to rollback on Java 8 and check if all is OK.
comment:6 by , 7 years ago
I've uninstalled Java JDK 9.0.1 that was installed via brew cask
and rolled back to Java 8 update 151
All works as expected without visible issues.
It's good to close this ticket or mark it as the issue connected with java 9
comment:7 by , 7 years ago
Keywords: | macosx java9 added |
---|---|
Summary: | JOSM is freezing when you attempt to move node along a line using Extrusion tool → Freeze on macOS / Java 9 when you attempt to move node along a line using Extrusion tool |
comment:8 by , 7 years ago
Owner: | changed from | to
---|---|
Status: | needinfo → new |
comment:9 by , 7 years ago
Description: | modified (diff) |
---|
comment:10 by , 7 years ago
Do you launch JOSM via WebStart or command line? Please attach your status report.
comment:11 by , 7 years ago
I run JOSM as a standalone application.
I tried to run JOSM via command line to get some information for reporting but except the message that Kendzi 3D was broken, I found nothing.
Also, ⌘
+W
hotkey for toggle wireframe mode didn't work as well.
comment:12 by , 7 years ago
OK. It seems there is a large number of bugs specific to java 9 and macOS right now (108).
comment:13 by , 7 years ago
One more question (there's a reason why we prefer status reports): what's your configured language, and what's your keyboard layout? macOS bugs are very often locale-specific.
comment:14 by , 7 years ago
I have English (ABC-Extended) as primary and system language. I use JOSM with Default (auto determined) locale.
Along with it, I have installed Ukrainian and Russian keyboard layouts.
This is my current state report
URL:http://josm.openstreetmap.de/svn/trunk Repository:UUID: 0c6e7542-c601-0410-84e7-c038aed88b3b Last:Changed Date: 2017-10-29 19:52:48 +0100 (Sun, 29 Oct 2017) Build-Date:2017-10-29 19:11:19 Revision:13053 Relative:URL: ^/trunk Identification: JOSM/1.5 (13053 en) Mac OS X 10.13.1 OS Build number: Mac OS X 10.13.1 (17B48) Memory Usage: 611 MB / 910 MB (65 MB allocated, but free) Java version: 1.8.0_151-b12, Oracle Corporation, Java HotSpot(TM) 64-Bit Server VM Screen: Display 69733568 1280x800 Maximum Screen Size: 1280x800 VM arguments: [-Djava.library.path=/Applications/JOSM.app/Contents/MacOS, -DLibraryDirectory=${HOME}/Library, -DDocumentsDirectory=${HOME}/Documents, -DApplicationSupportDirectory=${HOME}/Library/Application Support, -DCachesDirectory=${HOME}/Library/Caches, -DSandboxEnabled=false, -Dapple.laf.useScreenMenuBar=true, -Dcom.apple.macos.use-file-dialog-packages=true, -Dcom.apple.macos.useScreenMenuBar=true, -Dcom.apple.mrj.application.apple.menu.about.name=JOSM, -Dcom.apple.smallTabs=true]
comment:16 by , 7 years ago
Priority: | normal → major |
---|
comment:18 by , 7 years ago
Keywords: | macosx removed |
---|---|
Milestone: | → 17.11 |
Summary: | Freeze on macOS / Java 9 when you attempt to move node along a line using Extrusion tool → Freeze on Java 9 when you attempt to move node along a line using Extrusion tool |
Reproduced on Linux and Windows too.
comment:19 by , 7 years ago
Keywords: | javabug added |
---|---|
Priority: | major → critical |
Waw, it seems to an infinite loop in Java2D rendering code!
comment:20 by , 7 years ago
Could you make a thread dump (kill -3) to show the hot loop in marlin code. Dasher ?
Some details on the shape given to the renderer ?
Size, path, stroke attributes...
Laurent
comment:21 by , 7 years ago
Sure, here are the first details. Here is our calling code:
@Override public void paint(Graphics2D g2, MapView mv, Bounds box) { ... g2.setColor(helperColor); g2.setStroke(helperStrokeDash); // Draw a guideline along the normal. Line2D normline; Point2D centerpoint = mv.getPoint2D(p1.interpolate(p2, .5)); normline = createSemiInfiniteLine(centerpoint, normalUnitVector, g2); g2.draw(normline); // <- infinite loop here (100% cpu) ... }
Variables state for the first call:
g2 sun.java2d.SunGraphics2D alphafill MaskFill (id=1370) antialiasHint 2 [0x2] [^B] backgroundColor Color (id=1374) cachedFRC FontRenderContext (id=1375) clipRegion Region (id=1377) clipState 1 [0x1] [^A] composite AlphaComposite (id=1379) compositeState 0 [0x0] [^@ (NUL)] constrainClip null constrainX 0 [0x0] [^@ (NUL)] constrainY 0 [0x0] [^@ (NUL)] devClip Region (id=1382) drawpipe PixelToParallelogramConverter (id=1383) eargb -14336 [0xffffc800] fillpipe PixelToParallelogramConverter (id=1383) font Font (id=1389) fontInfo FontInfo (id=1391) fontMetrics null foregroundColor Color (id=1332) fractionalMetricsHint 1 [0x1] [^A] glyphVectorFontInfo null glyphVectorFRC null hints null imageComp CompositeType (id=1393) imagepipe DrawImage (id=1395) interpolationHint -1 [0xffffffff] interpolationType 1 [0x1] [^A] lastCAblit null lastCAcomp null lcdTextContrast 140 [0x8c] [^Ì] loops RenderLoops (id=1398) paint Color (id=1332) paintState 0 [0x0] [^@ (NUL)] pixel -14336 [0xffffc800] renderHint 0 [0x0] [^@ (NUL)] resolutionVariantHint 0 [0x0] [^@ (NUL)] shapepipe PixelToParallelogramConverter (id=1383) stroke BasicStroke (id=1336) strokeHint 0 [0x0] [^@ (NUL)] strokeState 2 [0x2] [^B] surfaceData BufImgSurfaceData (id=1400) textAntialiasHint 0 [0x0] [^@ (NUL)] textpipe AATextRenderer (id=1406) transform AffineTransform (id=1412) transformState 0 [0x0] [^@ (NUL)] transX 0 [0x0] [^@ (NUL)] transY 0 [0x0] [^@ (NUL)] usrClip GeneralPath (id=1414) validFontInfo false helperColor java.awt.Color[r=255,g=200,b=0] helperStrokeDash java.awt.BasicStroke cap 0 dash [4.0] dash_phase 0.0 join 0 miterlimit 10.0 width 1.0 centerPoint Point2D.Double[546.7863882441737, 595.5292435631711] normalUnitVector Point2D.Double[-0.7759523728971103, -0.6307914988293232] normline java.awt.geom.Line2D$Double x1 546.7863882441737 x2 -3.3326895165083923E9 y1 595.5292435631711 y2 -2.709228261275939E9
And here is the infinite loop in sun.java2d.marlin.Dasher.lineTo
(jdk 9.0.1):
@Override public void lineTo(float x1, float y1) { ... float leftInThisDashSegment; float dashdx, dashdy, p; while (true) { leftInThisDashSegment = _dash[idx] - phase; // Stays to 4.0 if (len <= leftInThisDashSegment) { // This is never true for us. Len is huge (4.29496704E9) _curCurvepts[0] = x1; _curCurvepts[1] = y1; goTo(_curCurvepts, 0, 4); // Advance phase within current dash segment phase += len; // TODO: compare float values using epsilon: if (len == leftInThisDashSegment) { phase = 0f; idx = (idx + 1) % dashLen; dashOn = !dashOn; } return; } dashdx = _dash[idx] * cx; // cx = -0.7759524 => dashdx = -3.1038096 dashdy = _dash[idx] * cy; // cy = -0.63079154 => dashdy = -2.5231662 if (phase == 0f) { // true _curCurvepts[0] = x0 + dashdx; // x0 = -272518.53 _curCurvepts[1] = y0 + dashdy; // y0 = -220992.17 } else { p = leftInThisDashSegment / _dash[idx]; _curCurvepts[0] = x0 + p * dashdx; _curCurvepts[1] = y0 + p * dashdy; } goTo(_curCurvepts, 0, 4); // _curCurvepts = [-272521.62, -220994.69, 3.0001056, 1.6513481, 2.9812324, 1.6598293, 2.7518036, 1.7459841, 4.590311, 1.6547815, 4.4771295, 1.6520241, 4.366947, 1.6513481, 4.2638865, 1.6513481] len -= leftInThisDashSegment; // 4.29496704E9 - 4.0 ==> we'll have to wait a very long time at this rate // Advance to next dash segment idx = (idx + 1) % dashLen; // (0 + 1) % 1 = 0 dashOn = !dashOn; phase = 0f; } ... }
I'm trying with JDK 10-ea and latest release of Marvin now.
follow-up: 23 comment:22 by , 7 years ago
Thanks so much for the report.
Marlin emits dashes in that loop for very long.
As jdk9 uses float, it suffers precision issue: the current accumulator is flawed.
I already experimented the kahan sum to preserve accuracy...
But I prefer using the double variant of Marlin which is the default in jdk10.
In Marlin 0.8.2 (@ github) I implemented a fast segment clipper,
as all these invisible dashes are counter productive.
I recommend anyway to fix your code in createSemiInfiniteLine() to:
- crop the line to the clip window (+ extra margin): max length= sqrt (w2 + h2)
- to have the best performance
It seems easy to do, isn't it ?
comment:23 by , 7 years ago
Replying to bourges.laurent@…:
Thanks so much for the report.
You're welcome, thank you for your work on Marlin and coming discuss the problem with us :)
I recommend anyway to fix your code in createSemiInfiniteLine() to:
- crop the line to the clip window (+ extra margin): max length= sqrt (w2 + h2)
- to have the best performance
Looks like the best solution indeed. Do you need I create a bug report with reproducer code on Github, or is the previous information enough for you?
comment:25 by , 7 years ago
Cc: | added |
---|
comment:26 by , 7 years ago
I read the code of createSemiInfLine() and it handles the viewport limits.
Maybe it is buggy (corner case ?)...
In your info, the Line2d is 500px to -2px so the scale is small.
How can the line length be 1E9 in Dasher ?
What is your scaling factor ?
I supposed the viewport corresponds to the painting area in pixel.
Certainly there is a confusion between device (pixel) & user (geo) spaces...
Ps: please send a reproducer on github or via marlin list or by mail
Laurent
comment:27 by , 7 years ago
Cc: | added |
---|
Guys, this bug could interest you as well :)
@Laurent: sure I'll create a proper issue on Github, thanks for your help.
comment:28 by , 7 years ago
Just a short note without any testing
- MapView does not use any scaling for painting. We use a 1:1 pixel mapping and do the math ourselves
- I once tracked a bug where a line was drawn from (0,0) in East/North space. Since you were probably editing in europe, this might be where x0/y0 are.
- Quick fix: You can use the MapViewPath class for drawing, it provides you with clipping.
comment:29 by , 7 years ago
It is not really a Marlin bug. Rather a pure JDK bug:
System.out.println(g.getDeviceConfiguration().getBounds();
Java 8:
java.awt.Rectangle[x=0,y=0,width=1261,height=949]
Java 9:
java.awt.Rectangle[x=0,y=0,width=2147483647,height=2147483647]
> WTF?!
That's why JOSM asks to the Java2D renderer to draw an infinite line. I have reproduced the freeze with Java 8 as well, with such an insane line length.
comment:30 by , 7 years ago
The bug has been introduced on purpose (see javabug:8072682 / http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/aafc0a279f95).
This is so WTF I had to create https://github.com/CodeFX-org/java-9-wtf/pull/3
@Laurent: do you agree with what they did? It seems so wrong to me!
comment:32 by , 7 years ago
I read the JBS bug and I agree the jdk change.
Graphics.getDeviceConfiguration() does not make sense on a buffered image.
However that jdk change hurts your code and the fix Graphics.getClipBounds() is the right thing to so.
You should inspect all your josm code to find any other usage of the buggy API.
Laurent
comment:33 by , 7 years ago
OK thanks :) I already checked and did not find any other call to Graphics.getDeviceConfiguration()
so it must be OK now :)
comment:34 by , 7 years ago
FYI I added a comment to https://bugs.openjdk.java.net/browse/JDK-8072682
The API behaviour change in JDK9 should be mentioned in release notes (or migration guide)
Can't reproduce. Can you please check on another OS (Linux or Windows) to see if it's Mac-specific?