NPE while accessing parent class after code changes

ZeroTurnaround Homepage Forums JRebel Support NPE while accessing parent class after code changes

This topic contains 2 replies, has 2 voices, and was last updated by  Meelis 1 month, 1 week ago.

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #61775

    agerasch
    Member

    Hi there,

    recently, I got some NPE while accessing the instance of an outer class using implicit “OuterClass.this” after JRebel reloads.

    I was able to write a (medium) small, absolutely useless Testclass to reproduce this error:

    import java.awt.Frame;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JDialog;
    import javax.swing.JList;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    
    public class JRebelTest extends JDialog {
    
    	private JList<String> list = null;
    	
    	private Timer repaintTimer;
    	
    	public JRebelTest() {
    		super((Frame) null, "JRebel Test", true);
    		
    		getContentPane().setLayout(new GridLayout(1, 1));
    		setSize(400, 400);
    		
    		// MOVE THIS BLOCK
    		repaintTimer = new Timer(1000, new ActionListener() {
    
    			@Override
    			public void actionPerformed(ActionEvent e) {
    				System.out.println("repainting");
    				repaint();
    				getBounds();
    			}
    		});
    		repaintTimer.start();
    		// MOVE THIS BLOCK 
    		
    		
    		reload();
    	}
    	
    	private void printTest() {
    		System.out.println("still working");
    	}
    	
    	
    	public void reload() {
    		System.out.println("Reloading...");
    		SwingUtilities.invokeLater(new Runnable() {
    			@Override
    			public void run() {
    				list = new JList<String>(new String[] { "Row 1", "Row 2" });
    				list.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
    					
    					@Override
    					public void valueChanged(ListSelectionEvent e) {
    						printTest();
    					}
    				});
    				
    				getContentPane().removeAll();
    				getContentPane().add(list);
    				
    				// TO HERE
    			}
    		});
    		
    	}
    	
    	public static void main(String[] args) {
    		JRebelTest frame = new JRebelTest();
    		frame.setAlwaysOnTop(true);
    		frame.setVisible(true);
    	}
    
    }

    The steps to reproduce the error are:

    1. Start the application
    2. Click to the list items to see that printTest() is called correctly
    3. Cut the code-block between “MOVE THIS BLOCK”
    4. Important: save the file and wait until JRebel reloaded the changes
    5. Click to the list items to see that printTest() is still working
    6. Paste the extracted code block to “TO HERE”
    7. Save the file and wait until JRebel reloaded the changes
    8. Click to the list items to see that printTest() is not working anymore

    During this test, I get the following output and error:

    2017-02-22 11:35:59 JRebel: [jrebel license init]
    Reloading...
    repainting
    still working
    still working
    still working
    still working
    repainting
    repainting
    repainting
    repainting
    repainting
    repainting
    repainting
    repainting
    repainting

    cutted the block and saved the file

    2017-02-22 11:36:10 JRebel: Reloading class 'JRebelTest$1'.
    2017-02-22 11:36:10 JRebel: Reloading class 'JRebelTest'.
    repainting
    repainting
    repainting
    repainting
    repainting
    repainting
    repainting
    still working
    still working
    still working
    repainting
    still working
    repainting
    repainting
    repainting

    pasted the block and saved the file

    2017-02-22 11:36:21 JRebel: Reloading class 'JRebelTest$1'.
    2017-02-22 11:36:21 JRebel: Reloading class 'JRebelTest'.
    repainting
    repainting

    clicked on one list item

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    	at JRebelTest$2.access$0(JRebelTest.java:51)
    	at JRebelTest$2$1.valueChanged(JRebelTest.java:59)
    	at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:184)
    	at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:164)
    	at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:211)
    	at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:405)
    	at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:415)
    	at javax.swing.DefaultListSelectionModel.setSelectionInterval(DefaultListSelectionModel.java:459)
    	at javax.swing.JList.setSelectionInterval(JList.java:2065)
    	at javax.swing.plaf.basic.BasicListUI$Handler.adjustSelection(BasicListUI.java:2739)
    	at javax.swing.plaf.basic.BasicListUI$Handler.mousePressed(BasicListUI.java:2695)
    	at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:280)
    	at java.awt.Component.processMouseEvent(Component.java:6530)
    	at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    	at java.awt.Component.processEvent(Component.java:6298)
    	at java.awt.Container.processEvent(Container.java:2236)
    	at java.awt.Component.dispatchEventImpl(Component.java:4889)
    	at java.awt.Container.dispatchEventImpl(Container.java:2294)
    	at java.awt.Component.dispatchEvent(Component.java:4711)
    	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
    	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4522)
    	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
    	at java.awt.Container.dispatchEventImpl(Container.java:2280)
    	at java.awt.Window.dispatchEventImpl(Window.java:2746)
    	at java.awt.Component.dispatchEvent(Component.java:4711)
    	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    	at java.awt.EventQueue.access$500(EventQueue.java:97)
    	at java.awt.EventQueue$3.run(EventQueue.java:709)
    	at java.awt.EventQueue$3.run(EventQueue.java:703)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    	at java.awt.EventQueue$4.run(EventQueue.java:731)
    	at java.awt.EventQueue$4.run(EventQueue.java:729)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:109)
    	at java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:184)
    	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
    	at java.awt.EventQueue.access$500(EventQueue.java:97)
    	at java.awt.EventQueue$3.run(EventQueue.java:709)
    	at java.awt.EventQueue$3.run(EventQueue.java:703)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    	at JRebelTest$2.access$0(JRebelTest.java:51)
    	at JRebelTest$2$1.valueChanged(JRebelTest.java:59)
    	at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:184)
    	at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:154)
    	at javax.swing.DefaultListSelectionModel.setValueIsAdjusting(DefaultListSelectionModel.java:685)
    	at javax.swing.JList.setValueIsAdjusting(JList.java:2140)
    	at javax.swing.plaf.basic.BasicListUI$Handler.mouseReleased(BasicListUI.java:2796)
    	at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:290)
    	at java.awt.Component.processMouseEvent(Component.java:6533)
    	at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    	at java.awt.Component.processEvent(Component.java:6298)
    	at java.awt.Container.processEvent(Container.java:2236)
    	at java.awt.Component.dispatchEventImpl(Component.java:4889)
    	at java.awt.Container.dispatchEventImpl(Container.java:2294)
    	at java.awt.Component.dispatchEvent(Component.java:4711)
    	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
    	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
    	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
    	at java.awt.Container.dispatchEventImpl(Container.java:2280)
    	at java.awt.Window.dispatchEventImpl(Window.java:2746)
    	at java.awt.Component.dispatchEvent(Component.java:4711)
    	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    	at java.awt.EventQueue.access$500(EventQueue.java:97)
    	at java.awt.EventQueue$3.run(EventQueue.java:709)
    	at java.awt.EventQueue$3.run(EventQueue.java:703)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    	at java.awt.EventQueue$4.run(EventQueue.java:731)
    	at java.awt.EventQueue$4.run(EventQueue.java:729)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:109)
    	at java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:184)
    	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
    	at java.awt.EventQueue.access$500(EventQueue.java:97)
    	at java.awt.EventQueue$3.run(EventQueue.java:709)
    	at java.awt.EventQueue$3.run(EventQueue.java:703)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
    repainting
    repainting
    repainting
    repainting
    repainting
    repainting
    repainting
    repainting
    repainting

    Could you please verify this?

    Thx,

    Andreas

    #61788

    Meelis
    Moderator

    Hi,

    Thanks for the reproducible testapp to describe the error. I can confirm that it reproduces on our end.
    We will investigate the error and will keep you informed once we have updates.

    #61949

    Meelis
    Moderator

    Hi,

    We recently made a few improvements to JRebel anonymous inner class handling and the example test-case should work correctly now. The fix is available in the nightly build here: https://zeroturnaround.com/software/jrebel/download/nightly-build/

    Specifically the error was caused by removing the anonymous inner class which caused nested inner classes not updating properly and adding the new nested inner class resulted it being attached to the wrong top level inner class.
    Let us know if you run into similar errors in the future.

    The fix will also be in the 7.0.6 release.

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.