I am writing a program that checks prices and if it increases past a set amount then lets the user know by putting into a JavaFX text area line by line with a time stamp, appendText() spits out 2 errors. The error codes don't point to anything specific which is causing me to go in circles.
Most of the code works and if I use System.out.print() instead the code runs perfectly, but if I use txtContent.appendText() then at a random time in the first five minutes I will get one of the following errors.
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Cannot read the array length because "this.lines" is null
at javafx.graphics#19/com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1222)
at javafx.graphics#19/com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:223)
at javafx.graphics#19/com.sun.javafx.text.PrismTextLayout.getBounds(PrismTextLayout.java:246)
at javafx.graphics#19/javafx.scene.text.Text.getLogicalBounds(Text.java:432)
at javafx.graphics#19/javafx.scene.text.Text.doComputeGeomBounds(Text.java:1187)
at javafx.graphics#19/javafx.scene.text.Text$1.doComputeGeomBounds(Text.java:149)
at javafx.graphics#19/com.sun.javafx.scene.shape.TextHelper.computeGeomBoundsImpl(TextHelper.java:90)
at javafx.graphics#19/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:117)
at javafx.graphics#19/javafx.scene.Node.updateGeomBounds(Node.java:3825)
at javafx.graphics#19/javafx.scene.Node.getGeomBounds(Node.java:3787)
at javafx.graphics#19/javafx.scene.Node.getLocalBounds(Node.java:3735)
at javafx.graphics#19/javafx.scene.Node$MiscProperties$3.computeBounds(Node.java:6825)
at javafx.graphics#19/javafx.scene.Node$LazyBoundsProperty.get(Node.java:9840)
at javafx.graphics#19/javafx.scene.Node$LazyBoundsProperty.get(Node.java:9810)
at javafx.graphics#19/javafx.scene.Node.getBoundsInLocal(Node.java:3415)
at javafx.controls#19/javafx.scene.control.skin.TextAreaSkin$ContentView.layoutChildren(TextAreaSkin.java:1324)
at javafx.graphics#19/javafx.scene.Parent.layout(Parent.java:1207)
at javafx.graphics#19/javafx.scene.Parent.layout(Parent.java:1214)
at javafx.graphics#19/javafx.scene.Parent.layout(Parent.java:1214)
at javafx.graphics#19/javafx.scene.Parent.layout(Parent.java:1214)
at javafx.graphics#19/javafx.scene.Parent.layout(Parent.java:1214)
at javafx.graphics#19/javafx.scene.Parent.layout(Parent.java:1214)
at javafx.graphics#19/javafx.scene.Parent.layout(Parent.java:1214)
at javafx.graphics#19/javafx.scene.Scene.doLayoutPass(Scene.java:592)
at javafx.graphics#19/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2512)
at javafx.graphics#19/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:407)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics#19/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:406)
at javafx.graphics#19/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:436)
at javafx.graphics#19/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:575)
at javafx.graphics#19/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:555)
at javafx.graphics#19/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:548)
at javafx.graphics#19/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:352)
at javafx.graphics#19/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics#19/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics#19/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:1589)
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 2
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
at java.base/java.util.Objects.checkIndex(Objects.java:385)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
at javafx.base#19/com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
at javafx.base#19/com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:305)
at javafx.graphics#19/javafx.scene.Parent.updateCachedBounds(Parent.java:1704)
at javafx.graphics#19/javafx.scene.Parent.recomputeBounds(Parent.java:1648)
at javafx.graphics#19/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1501)
at javafx.graphics#19/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:115)
at javafx.graphics#19/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:84)
at javafx.graphics#19/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBoundsImpl(RegionHelper.java:78)
at javafx.graphics#19/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBounds(RegionHelper.java:62)
at javafx.graphics#19/javafx.scene.layout.Region.doComputeGeomBounds(Region.java:3355)
at javafx.graphics#19/javafx.scene.layout.Region$1.doComputeGeomBounds(Region.java:168)
at javafx.graphics#19/com.sun.javafx.scene.layout.RegionHelper.computeGeomBoundsImpl(RegionHelper.java:89)
at javafx.graphics#19/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:117)
at javafx.graphics#19/javafx.scene.Node.updateGeomBounds(Node.java:3825)
at javafx.graphics#19/javafx.scene.Node.getGeomBounds(Node.java:3787)
at javafx.graphics#19/javafx.scene.Node.getLocalBounds(Node.java:3735)
at javafx.graphics#19/javafx.scene.Node.intersectsBounds(Node.java:5270)
at javafx.graphics#19/javafx.scene.Node$1.intersectsBounds(Node.java:559)
at javafx.graphics#19/com.sun.javafx.scene.NodeHelper.intersectsBounds(NodeHelper.java:264)
at javafx.graphics#19/javafx.scene.layout.Region.doPickNodeLocal(Region.java:3224)
at javafx.graphics#19/javafx.scene.layout.Region$1.doPickNodeLocal(Region.java:184)
at javafx.graphics#19/com.sun.javafx.scene.layout.RegionHelper.pickNodeLocalImpl(RegionHelper.java:104)
at javafx.graphics#19/com.sun.javafx.scene.NodeHelper.pickNodeLocal(NodeHelper.java:130)
at javafx.graphics#19/javafx.scene.Node.pickNode(Node.java:5180)
at javafx.graphics#19/javafx.scene.Scene$MouseHandler.pickNode(Scene.java:4037)
at javafx.graphics#19/javafx.scene.Scene.pick(Scene.java:2067)
at javafx.graphics#19/javafx.scene.Scene$MouseHandler.process(Scene.java:3847)
at javafx.graphics#19/javafx.scene.Scene.processMouseEvent(Scene.java:1887)
at javafx.graphics#19/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2620)
at javafx.graphics#19/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
at javafx.graphics#19/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics#19/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
at javafx.graphics#19/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
at javafx.graphics#19/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
at javafx.graphics#19/com.sun.glass.ui.View.handleMouseEvent(View.java:551)
at javafx.graphics#19/com.sun.glass.ui.View.notifyMouse(View.java:937)
at javafx.graphics#19/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics#19/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:1589)
Normally when I get errors like this I will follow errors to the part that I wrote something incorrect or made some mistake with my work. But these don't point to anything in particular other than my runLoop which is pretty simple.
try
{
Database.deleteLastRow();
Database.updateRows();
JSONAccess.createNewRow();
if(increaseCounter)
{
rowCounter++;
}
if(rowCounter >= Main.calculatedRows)
{
if(testLine)
{
System.out.println("Starting");
testLine = false;
}
increaseCounter = false;
MainGUI.txtContent.appendText("\n New Section");
Database.compareValues();
}
}
catch (Exception e)
{
MainGUI.btnStart.setDisable(false);
MainGUI.btnStop.setDisable(true);
System.out.println("Test to see if something goes wrong");
}
public static void compareValues() throws Exception
{
Class.forName("org.hsqldb.jdbc.JDBCDriver");
for (String tableName : symbolsList)
{
String compareSql = "SELECT * FROM tbl_" + tableName + " ORDER BY id";
prepStatement = connection.prepareStatement(compareSql);
ResultSet rs = prepStatement.executeQuery();
int rowNum = 1;
while (rs.next())
{
if (rowNum == 1)
{
dblNew = rs.getDouble("val");
}
if (rowNum == Main.calculatedRows)
{
dblOld = rs.getDouble("val");
}
rowNum = Main.calculatedRows;
}
mathsCompare(tableName, dblNew, dblOld);
}
}
public static void mathsCompare(String tableName1, double dblNew1, double dblOld1) throws Exception
{
if(dblNew1>dblOld1)
{
double dblChange = ((dblNew1-dblOld1)/dblOld1)*100;
if(dblChange >= Main.dblPercentage)
{
MainGUI.txtContent.appendText("\n" + tableName1);
System.out.print("\n" + tableName1);
}
}
}
If I have both System.out.println and MainGUI.txtContent.appendText enabled then the console gets an extra set of values out before the error comes out but thats when I get stumped
Any help appreciated.
Related
protected Void doInBackground(Void... voids) {
...
ABV = elem.select("td > span.muted").text();
Log.d("myLOG_ABV", ABV);
Log.d("myLOG_ABVlength", String.valueOf(ABV.length()));
/*String temp_ABV = ABV.substring(ABV.length()-6, ABV.length());*/
... }
Result
D/myLOG_ABV: Russian River Brewing Company American Wild Ale | 7.50%
D/myLOG_ABVlength: 55
and then, I cancled the annotation code.
...
ABV = elem.select("td > span.muted").text();
Log.d("myLOG_ABV", ABV);
Log.d("myLOG_ABVlength", String.valueOf(ABV.length()));
***String temp_ABV = ABV.substring(ABV.length()-6, ABV.length());***
...
Result
Caused by: java.lang.StringIndexOutOfBoundsException: length=0;
index=-6
Why am I getting StringIndexOutOfBoundsException error in this substring method?
I got the result that 'ABVlength : 55' in my code with annotation.
But after cancellation of annotation, I got StringIndexOutOfBoundsException.
Seriously, I am fighting with this code for 7hours 30minutes.
So we have:
***String temp_ABV = ABV.substring(ABV.length()-6, ABV.length());***
Caused by: java.lang.StringIndexOutOfBoundsException: length=0; index=-6
How can you get an index of -6 in this situation? ABV must have zero length, i.e. "".
It may be the case that ABV should have at least six characters, but that indicates a bug elsewhere.
What to do?
First and foremost, validate your inputs.
Somewhere you would normally want something like:
if (abv.length() < 6) {
throw new IllegalArgumentException("...");
}
Next find where that value is coming from and fix the bug.
Looks like you're parsing some kind of external document. In this case you may want the handling to be more lenient:
int abvLen = abv.length();
int abvEndIndex = abvLen - 6;
if (abvEndIndex < 0) {
log.error("ABV length less than 6", abv);
abvEndIndex = 0;
}
String abvEnd = abv.substring(abvEndIndex, abvLen);
My problem is that my JavaFx application has gone to be very slow. Both in the start of the application and in some of the triggered events. It is a calendar application that uses a GridPane, that I am modifying. I have this method:
t.setOnMouseClicked(event->{
long starttid = System.currentTimeMillis();
System.out.println("start");
if (markedTimeEnd != null && markedTimeStart != null) {
colorMinutes(markedTimeStart, markedTimeEnd, Color.BLACK, bakrundWhite);
} else if (markedTimeStart != null) {
colorMinutes(markedTimeStart, markedTimeStart, Color.BLACK, bakrundWhite);
}
long tidNu = System.currentTimeMillis();
long tid = tidNu-starttid;
System.out.println("Print first time:\n"+tid);
int minutTid = gridPane.getRowIndex(t);
int timmeTimme = minutTid / 60;
int minutMinut = minutTid - (60 * timmeTimme);
markedTimeStart = new TidPunkt(timmeTimme, minutMinut);
markedTimeEnd = null;
tid = System.currentTimeMillis() -tidNu;
tidNu = System.currentTimeMillis();
System.out.println("Time for the middel calculations:\n"+tid);
if (markedTimeEnd != null && markedTimeStart != null) {
colorMinutes(markedTimeStart, markedTimeEnd, Color.GREEN,bakrundGren);
} else if (markedTimeStart != null) {
colorMinutes(markedTimeStart, markedTimeStart, Color.GREEN,bakrundGren);
}
event.consume();
repaintAll();
System.out.println("Time to end:\n"+(System.currentTimeMillis()-tidNu));
});
And the code for the colorMinutes:
private void colorMinutes(TidPunkt markedTimeStart, TidPunkt markedTimeEnd, Color colorText, Background colorOther) {
System.out.println("The call is comming");
int startBothTogether = markedTimeStart.getTimme() * 100 + markedTimeStart.getMinut();
int endBothTogether = markedTimeEnd.getTimme() * 100 + markedTimeEnd.getMinut();
System.out.println("Befor filter");
gridPane.getChildren().stream()//parallelStream()
.filter(x-> x.getId()!=null)
.filter(y-> y.getId().matches("\\d\\d:\\d\\d"))
.filter(pp->{
int hoursForPart = Integer.parseInt(((Node) pp).getId().split(":")[0]);
int miutesForPart = Integer.parseInt(((Node) pp).getId().split(":")[1]);
int bothTogether = hoursForPart * 100 + miutesForPart;
if (bothTogether >= startBothTogether && bothTogether <= endBothTogether)
return true;
else
return false;
})
.forEach(pp->{
Platform.runLater(() -> {
System.out.println("Changing collor ----");
if(pp instanceof Pane){
((Pane) pp).setBackground(colorOther)
}else{
((Text) pp).setFill(colorText);
}
});
});
}
But it takes very long before it is change on the screen and it freezes sometime after what I can se is the finish of these methods by the System.out.println. I have been trying to profile but can't figure it out(best I have come up with it that is seems to be a big call tree, of javaFx "stuff" when exiting the method). The System.out.println prints is:
start
Print first time:
0
Time for the middel calculations:
0
The call is comming
Befor filter
Time to end:
373
Changing collor ----
Changing collor ----
Changing collor ----
Changing collor ----
But from button press to all is being color correct it takes many seconds.
The full code can be found here
You're posting to many Runnables using Platform.runLater. There is no reason to use Platform.runLater here at all, since the onMouseClicked event handler is executed on the javafx application thread anyways.
Using
.forEach(pp->{
if(pp instanceof Pane){
((Pane) pp).setBackground(colorOther)
}else{
((Text) pp).setFill(colorText);
}
});
Should improve the performance drastically.
Furthermore you seem to add a huge amout of Nodes in your repaintAll method (more specifically the ritaGrundKalender method) without removing Nodes which increases the number of Runnables for every click. I suggest you change this behavior.
I made a color palette with a jPanel and a JLabel array in it. At first it worked well, but then i put some other jLabels out of the JPanel and added them some events. Now I keep getting this error:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:747)
at java.util.TimSort.mergeAt(TimSort.java:483)
at java.util.TimSort.mergeCollapse(TimSort.java:410)
at java.util.TimSort.sort(TimSort.java:214)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
at javax.swing.SortingFocusTraversalPolicy.enumerateAndSortCycle(SortingFocusTraversalPolicy.java:136)
at javax.swing.SortingFocusTraversalPolicy.getFocusTraversalCycle(SortingFocusTraversalPolicy.java:110)
at javax.swing.SortingFocusTraversalPolicy.getFirstComponent(SortingFocusTraversalPolicy.java:435)
at javax.swing.LayoutFocusTraversalPolicy.getFirstComponent(LayoutFocusTraversalPolicy.java:166)
at javax.swing.SortingFocusTraversalPolicy.getDefaultComponent(SortingFocusTraversalPolicy.java:515)
at java.awt.FocusTraversalPolicy.getInitialComponent(FocusTraversalPolicy.java:169)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:380)
at java.awt.Component.dispatchEventImpl(Component.java:4731)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:723)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:682)
at java.awt.EventQueue$3.run(EventQueue.java:680)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:696)
at java.awt.EventQueue$4.run(EventQueue.java:694)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:693)
at java.awt.SequencedEvent.dispatch(SequencedEvent.java:116)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:721)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:682)
at java.awt.EventQueue$3.run(EventQueue.java:680)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:696)
at java.awt.EventQueue$4.run(EventQueue.java:694)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:693)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
I tried to remove everything i've done after first time i got this error, but still keep getting it. When i change the layout from GridLayout to anything else, then the error disappears, but the code becomes useless. So i need GridLayout. When i move everything in that JPanel to another JPanel, the error also goes away. But when i remove the first JPanel, error comes back.
By the way, the program works, but it's not pleasent to keep getting errors...
Edit: When i use less than 225 color, there's no error. I'm really curious about what's happening. Any explanation would be appreciated...
It seems to me like you've hit a bug in the JDK since the error seems to come from Swing classes.
Options:
Define the property java.util.Arrays.useLegacyMergeSort as true. Either using in your code the line
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
before any Swing code. As the first line in the main method should work.
Or adding
-Djava.util.Arrays.useLegacyMergeSort=true
to your starting options (in the console, or in the project properties in an IDE, Ant script, etc.)
Upgrade your JDK and see if the problem goes away
Downgrade to Java 6
Report my findings:
-Djava.util.Arrays.useLegacyMergeSort=true
works
but
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
does not work.
It is due to the fact that in JDK Arrays.class
static final class LegacyMergeSort {
private static final boolean userRequested = ...
It is a static variable which is defined when jvm starts. Setting System property in the program will have no effect if the class has been loaded into jvm.
I have beeing monitoring the LegacyMergeSort.userRequested variable, and the findings confirmed with above statement.
Update:
The program must set system properties before java.util.Arrays is loaded to classloader.
Otherwise, once it is loaded, setting the properties is not going to be useful due to the reason mentioned above.
Make sure nothing else loaded Arrays.class:
By putting following code to your program to test:
java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", new Class[] { String.class });
m.setAccessible(true);
ClassLoader cl = ClassLoader.getSystemClassLoader();
Object test1 = m.invoke(cl, "java.util.Arrays");
System.out.println("test1 loaded? ->" + (test1 != null));
[Update]
This solution unfortunately is not guaranteed to solve the problem in all cases. It is not enough to patch the default SortingFocusTraversalPolicy
of the KeyboardFocusManager.
I recommend to read the answer by Robin Loxley below, including his Update.
[/Update]
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:868)
This problem is caused by a bug in javax.swing.LayoutComparator.
The following class installs a fixed version of javax.swing.LayoutComparator, which does not violate the contract of Comparator<Component>. This (or any other) fixed version of javax.swing.LayoutComparator should be submitted to Oracle by some Oracle contributor.
package ...;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.FocusTraversalPolicy;
import java.awt.KeyboardFocusManager;
import java.awt.Window;
import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.ListIterator;
import javax.swing.JRootPane;
import javax.swing.SortingFocusTraversalPolicy;
import javax.swing.UIManager;
/**
* Uses reflection to install a fixed version of {#link javax.swing.LayoutComparator} to solve the
* LayoutFocusTraversalPolicy/TimSort problem.
*
* <p>
* <code>java.lang.IllegalArgumentException: Comparison method violates its general contract!</code>
* <br/>
* {#code at java.util.TimSort.mergeHi(TimSort.java:868)}
* </p>
* <p>
* Usage: call {#code Class.forName(LayoutFocusTraversalPolicyTimSortBugFixer.class.getName())}
* before creating Swing components.
* </p>
*
* #author Burkhard Strauss
* #since Feb 2015
*/
public class LayoutFocusTraversalPolicyTimSortBugFixer
{
static
{
UIManager.getUI(new JRootPane()); // make Swing install the SortingFocusTraversalPolicy
final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager
.getCurrentKeyboardFocusManager();
final FocusTraversalPolicy focusTraversalPolicy = keyboardFocusManager
.getDefaultFocusTraversalPolicy();
boolean fixed = false;
if (focusTraversalPolicy instanceof SortingFocusTraversalPolicy)
{
try
{
final Field field = SortingFocusTraversalPolicy.class.getDeclaredField("comparator");
final boolean accessible = field.isAccessible();
try
{
field.setAccessible(true);
field.set(focusTraversalPolicy, new LayoutComparator());
fixed = true;
}
finally
{
field.setAccessible(accessible);
}
}
catch (final Exception e)
{
}
}
if (!fixed)
{
Loggers.getLoggerFor(LayoutFocusTraversalPolicyTimSortBugFixer.class).warn("could not fix the bug");
}
}
/**
* Fixed version of {#link javax.swing.LayoutComparator}.
* <p>
* Search for 'bugfix' in the code.
* </p>
*
* #author Burkhard Strauss
* #since Feb 2015
*/
#SuppressWarnings("serial")
private static class LayoutComparator implements Comparator<Component>, java.io.Serializable
{
private static final int ROW_TOLERANCE = 10;
private boolean horizontal = true;
private boolean leftToRight = true;
#SuppressWarnings("unused")
void setComponentOrientation(final ComponentOrientation orientation)
{
horizontal = orientation.isHorizontal();
leftToRight = orientation.isLeftToRight();
}
#Override
public int compare(Component a, Component b)
{
if (a == b)
{
return 0;
}
// Row/Column algorithm only applies to siblings. If 'a' and 'b'
// aren't siblings, then we need to find their most inferior
// ancestors which share a parent. Compute the ancestory lists for
// each Component and then search from the Window down until the
// hierarchy branches.
if (a.getParent() != b.getParent())
{
final LinkedList<Component> aAncestory = new LinkedList<Component>();
for (; a != null; a = a.getParent())
{
aAncestory.add(a);
if (a instanceof Window)
{
break;
}
}
if (a == null)
{
// 'a' is not part of a Window hierarchy. Can't cope.
throw new ClassCastException();
}
final LinkedList<Component> bAncestory = new LinkedList<Component>();
for (; b != null; b = b.getParent())
{
bAncestory.add(b);
if (b instanceof Window)
{
break;
}
}
if (b == null)
{
// 'b' is not part of a Window hierarchy. Can't cope.
throw new ClassCastException();
}
for (ListIterator<Component> aIter = aAncestory.listIterator(aAncestory.size()), bIter = bAncestory
.listIterator(bAncestory.size());;)
{
if (aIter.hasPrevious())
{
a = aIter.previous();
}
else
{
// a is an ancestor of b
return -1;
}
if (bIter.hasPrevious())
{
b = bIter.previous();
}
else
{
// b is an ancestor of a
return 1;
}
if (a != b)
{
break;
}
}
}
final int ax = a.getX(), ay = a.getY(), bx = b.getX(), by = b.getY();
int zOrder = a.getParent().getComponentZOrder(a) - b.getParent().getComponentZOrder(b);
{
//
// Here is the bugfix:
// Don't return 0 if a != b. This would violate the contract of
// Comparator<Component>.compare().
//
if (zOrder == 0)
{
zOrder = -1;
}
}
if (horizontal)
{
if (leftToRight)
{
// LT - Western Europe (optional for Japanese, Chinese, Korean)
if (Math.abs(ay - by) < ROW_TOLERANCE)
{
return (ax < bx) ? -1 : ((ax > bx) ? 1 : zOrder);
}
else
{
return (ay < by) ? -1 : 1;
}
}
else
{ // !leftToRight
// RT - Middle East (Arabic, Hebrew)
if (Math.abs(ay - by) < ROW_TOLERANCE)
{
return (ax > bx) ? -1 : ((ax < bx) ? 1 : zOrder);
}
else
{
return (ay < by) ? -1 : 1;
}
}
}
else
{ // !horizontal
if (leftToRight)
{
// TL - Mongolian
if (Math.abs(ax - bx) < ROW_TOLERANCE)
{
return (ay < by) ? -1 : ((ay > by) ? 1 : zOrder);
}
else
{
return (ax < bx) ? -1 : 1;
}
}
else
{ // !leftToRight
// TR - Japanese, Chinese, Korean
if (Math.abs(ax - bx) < ROW_TOLERANCE)
{
return (ay < by) ? -1 : ((ay > by) ? 1 : zOrder);
}
else
{
return (ax > bx) ? -1 : 1;
}
}
}
}
}
}
I just ran into the same error and spent a good amount of time tracking it down. To help others who run into this error it is important to know how to test TimSort. The checks that violate the transitivity contract and throw this error are deep in the algorithm and require a test to meet certain criteria before this problem can be reproduced.
Create a list with 32 or more objects.
Within that list, there needs to two or more runs.
Each run must contain 3 or more objects.
Once you meet those two criteria you can begin testing for this failure.
A run is defined as a sub-set of the list where each item is already in the desired ordered state.
It is not enough to patch LayoutComparator as suggerested above. This fix does not work in my case.
The issue was fixed in JDK 8 (8u45 at least).
SortingFocusTraversalPolicy to use legacy Merge Sort Method.
There is nothing wrong with the JDK.
I was facing the same issue since 2 days & finally got to know that bug was with my date-format.
In my API response few dates were in "dd-MM-yyyy HH:mm" format while few of them were in "dd/MM/yyyy HH:mm" format.
Same issue while comparing integers, May be your List is having some null values.
Here is my code, which is working like a charm
Collections.sort(root_array, new Comparator<RootResponseItem>(){
public int compare(RootResponseItem o1, RootResponseItem o2){
Date date1 = new Date();
String dtStart = o1.getSectors().get(0).getDeparture().getDate() + " " + o1.getSectors().get(0).getDeparture().getTime();
dtStart = dtStart.replaceAll("-","/");
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
try {
date1 = format.parse(dtStart);
} catch (ParseException e) {
e.printStackTrace();
}
Date date2 = new Date();
String dtStart2 = o2.getSectors().get(0).getDeparture().getDate() + " " + o2.getSectors().get(0).getDeparture().getTime();
dtStart2 = dtStart2.replaceAll("-","/");
SimpleDateFormat format2 = new SimpleDateFormat("dd/MM/yyyy HH:mm");
try {
date2 = format2.parse(dtStart2);
} catch (ParseException e) {
e.printStackTrace();
}
return date1.compareTo(date2);
}
});
Here is my managed Bean class,
public class ChartBean implements Serializable {
private PieChartModel pieModel;
public ChartBean(){
createPieModel();
}
public PieChartModel getPieModel() {
return pieModel;
}
private void createPieModel(){
try {
pieModel = new PieChartModel();
String query = "SELECT b.countryname,count(b.countryname) FROM info.summery a,info.countrymcc b;";
Connector conn = new Connector();
Statement str = (Statement) conn.getConn().createStatement();
ResultSet res = str.executeQuery(query);
while(res.next()){
pieModel.set(res.getString(1), Integer.parseInt(res.getString(2)));
}
} catch (SQLException ex) {
Logger.getLogger(ChartBean.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
But the problem is when it is compiled it gives an error like this "Cant instantiate class: org.primefaces.examples.view.ChartBean". What is the reason??
StackTrace:
Caused by: java.lang.NullPointerException at
org.primefaces.examples.view.ChartBean.createPieModel(ChartBean.java:45) at
org.primefaces.examples.view.ChartBean.<init>(ChartBean.java:32) at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorI
mpl.java:39) at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorA
ccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at
java.lang.Class.newInstance0(Class.java:355) at java.lang.Class
By a process of elimination, the problem is happening because conn.getConn() is returning null. You should be able to simply confirm that the exception occurs at that line (by checking the line number!), and we know that conn cannot be null, so it must be result of getConn() that is null.
That's about as far as I can go without knowing what the Connector class is and how its getConn() method works.
For the record, here's how I eliminated other possibilities.
The NPE is being thrown in the createPieModel call ... and not in some method called from createPieModel:
1. private void createPieModel(){
2. try {
3. pieModel = new PieChartModel();
4. String query = "SELECT b.countryname,count(b.countryname) FROM info.summery a,info.countrymcc b;";
5. Connector conn = new Connector();
6. Statement str = (Statement) conn.getConn().createStatement();
7. ResultSet res = str.executeQuery(query);
8. while(res.next()){
9. pieModel.set(res.getString(1), Integer.parseInt(res.getString(2)));
10. }
11. } catch (SQLException ex) {
12. Logger.getLogger(ChartBean.class.getName()).log(Level.SEVERE, null, ex);
13. }
14. }
It cannot be line 3 because any NPE would be thrown in the constructor.
It cannot be line 4
It cannot be line 5 - see line 3
It could be line 6
It cannot be line 7 - because str must be non-null (if we get that far)
It cannot be line 8 - because executeQuery never returns null
It cannot be line 9 - because res and pieModel must be non-null.
It cannot be line 12 - because nothing there can return a null.
Hence it can only happen on line 6.
I know that the line in error is to_return = find(list,false); How can I get the line number of this line when there is NullPointerException type of error? Or in line number in general?
I tried few things. The closest is this one Called.getLineNumber() which gives me the line number of StackTraceElement Called = new Throwable().fillInStackTrace().getStackTrace()[0];
public TestObject[] myfind(Subitem list )throws Exception{
TestObject[]to_return=null;
try {
to_return = find(list,false);
}
catch (RationalTestException ex) {
//logStoreException(ex);
StackTraceElement Called = new Throwable().fillInStackTrace().getStackTrace()[0];
StackTraceElement Calling = new Throwable().fillInStackTrace().getStackTrace()[1];
throw new Exception (this.add_debugging_info(Called, Calling, ex.getMessage()));
}
catch (NullPointerException npe) {
StackTraceElement Called = new Throwable().fillInStackTrace().getStackTrace()[0];
StackTraceElement Calling = new Throwable().fillInStackTrace().getStackTrace()[1];
logStoreException(npe);
System.out.println("Line number: "+npe.getStackTrace()[0].getLineNumber());
System.out.println("Line number2: "+Integer.toString(Called.getLineNumber()));
System.out.println(this.add_debugging_info(Called, Calling, npe.getMessage()));
throw new Exception (this.add_debugging_info(Called, Calling, npe.getMessage()));
}
catch (Exception ex) {
StackTraceElement Called = new Throwable().fillInStackTrace().getStackTrace()[0];
StackTraceElement Calling = new Throwable().fillInStackTrace().getStackTrace()[1];
throw new Exception (this.add_debugging_info(Called, Calling, ex.getMessage()));
}
finally {
//unregisterAll();
//unregister(to);
return to_return;
}
}
If you just want the current stack trace, use Thread.currentThread().getStackTrace()
If you want to force the JVM to fill in the stack traces, please set the option -XX:-OmitStackTraceInFastThrow on your JVM.
When running in Eclipse, to get the line number itself, you need to get the StackTrace array and call getLineNumber() on it.
The following worked for me in my Utils class, isSessionConnectible method:
... catch (ClassFormatError cfe) {
logger.error("Problem ClassFormatError connecting. " + cfe.getMessage() + " " + cfe.getCause());
int size = cfe.getStackTrace().length - 1;
logger.error(" Root cause: " + cfe.getStackTrace()[size].getMethodName() + " " + cfe.getStackTrace()[size].getClassName());
if (size>1) {
logger.error(" Penultimate cause: method=" + cfe.getStackTrace()[size-1].getMethodName() + " class=" + cfe.getStackTrace()[size-1].getClassName() +
" line=" + cfe.getStackTrace()[size-1].getLineNumber());
}
Result when thrown:
2018-07-06 12:00:12 ERROR Utils:319 - Problem ClassFormatError connecting to Hibernate. Absent Code attribute in method that is not native or abstract in class file javax/transaction/SystemException null
2018-07-06 12:00:12 ERROR Utils:322 - Root cause: main <mypackage>.Utils
2018-07-06 12:00:12 ERROR Utils:324 - Penultimate cause: method=isSessionConnectible class=<mypackage>.Utils line=306
BTW, in Eclipse, make sure that Window --> Preferences --> Java --> Compiler has the checkbox marked at "Add line number attributes to generated class files".