Re: [icedtea-web] Regression after refactoring for XDG specification

Jacob Wisor gitne at excite.co.jp
Tue Jul 30 09:14:53 PDT 2013


"Jiri Vanek"<jvanek at xxxxxxxxxx> wrote:
> On 07/29/2013 03:00 PM, Jacob Wisor wrote:
> > "Jiri Vanek"<jvanek at xxxxxxxxxx> wrote:
> >> On 07/27/2013 02:43 PM, Jiri Vanek wrote:
> >>> On 07/27/2013 01:49 AM, Jacob Wisor wrote:
> >>>> Hello,
> >>>>
> >>>> I get the following regression since the code has been refactored to conform to the XDG specification, at least on Windows, but it should apply to Un*x systems too.
> >>>>
> >>>> Exception occurred during event dispatching:
> >>>> java.lang.NullPointerException
> >>>>            at net.sourceforge.jnlp.cache.CacheDirectory.getDirStructure(CacheDirect
> >>>> ory.java:56)
> >>>>            at net.sourceforge.jnlp.controlpanel.CachePane.generateData(CachePane.ja
> >>>> va:360)
> >>>>            at net.sourceforge.jnlp.controlpanel.CachePane.populateTable(CachePane.j
> >>>> ava:343)
> >>>>            at net.sourceforge.jnlp.controlpanel.CachePane.access$500(CachePane.java
> >>>> :66)
> >>>>            at net.sourceforge.jnlp.controlpanel.CachePane$8.run(CachePane.java:312)
> >>>>
> >>>>            at java.awt.event.InvocationEvent.dispatch(Unknown Source)
> >>>>            at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
> >>>>            at java.awt.EventQueue.access$400(Unknown Source)
> >>>>            at java.awt.EventQueue$2.run(Unknown Source)
> >>>>            at java.awt.EventQueue$2.run(Unknown Source)
> >>>>            at java.security.AccessController.doPrivileged(Native Method)
> >>>>            at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown
> >>>> Source)
> >>>>            at java.awt.EventQueue.dispatchEvent(Unknown Source)
> >>>>            at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
> >>>>            at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
> >>>>            at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
> >>>>            at java.awt.Dialog$1.run(Unknown Source)
> >>>>            at java.awt.Dialog$3.run(Unknown Source)
> >>>>            at java.security.AccessController.doPrivileged(Native Method)
> >>>>            at java.awt.Dialog.show(Unknown Source)
> >>>>            at java.awt.Component.show(Unknown Source)
> >>>>            at java.awt.Component.setVisible(Unknown Source)
> >>>>            at java.awt.Window.setVisible(Unknown Source)
> >>>>            at java.awt.Dialog.setVisible(Unknown Source)
> >>>>            at net.sourceforge.jnlp.controlpanel.CacheViewer.showCacheDialog(CacheVi
> >>>> ewer.java:149)
> >>>>            at net.sourceforge.jnlp.controlpanel.TemporaryInternetFilesPanel$4.actio
> >>>> nPerformed(TemporaryInternetFilesPanel.java:206)
> >>>>            at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
> >>>>            at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
> >>>>            at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
> >>>>            at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
> >>>>            at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Sour
> >>>> ce)
> >>>>            at java.awt.Component.processMouseEvent(Unknown Source)
> >>>>            at javax.swing.JComponent.processMouseEvent(Unknown Source)
> >>>>            at java.awt.Component.processEvent(Unknown Source)
> >>>>            at java.awt.Container.processEvent(Unknown Source)
> >>>>            at java.awt.Component.dispatchEventImpl(Unknown Source)
> >>>>            at java.awt.Container.dispatchEventImpl(Unknown Source)
> >>>>            at java.awt.Component.dispatchEvent(Unknown Source)
> >>>>            at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
> >>>>            at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
> >>>>            at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
> >>>>            at java.awt.Container.dispatchEventImpl(Unknown Source)
> >>>>            at java.awt.Window.dispatchEventImpl(Unknown Source)
> >>>>            at java.awt.Component.dispatchEvent(Unknown Source)
> >>>>            at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
> >>>>            at java.awt.EventQueue.access$400(Unknown Source)
> >>>>            at java.awt.EventQueue$2.run(Unknown Source)
> >>>>            at java.awt.EventQueue$2.run(Unknown Source)
> >>>>            at java.security.AccessController.doPrivileged(Native Method)
> >>>>            at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown
> >>>> Source)
> >>>>            at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown
> >>>> Source)
> >>>>            at java.awt.EventQueue$3.run(Unknown Source)
> >>>>            at java.awt.EventQueue$3.run(Unknown Source)
> >>>>            at java.security.AccessController.doPrivileged(Native Method)
> >>>>            at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown
> >>>> Source)
> >>>>            at java.awt.EventQueue.dispatchEvent(Unknown Source)
> >>>>            at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
> >>>>            at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
> >>>>            at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
> >>>>            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
> >>>>            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
> >>>>            at java.awt.EventDispatchThread.run(Unknown Source)
> >>>>
> >>>> The cause of this NullPointerException is a missing %USERPROFILE%.cacheicedtea-webcache or ~/.cache/icedtea-web/cache folder. There should be check for existance before trying to list files in this folder, if non-existent it should be created. Btw. since net.sourceforge.jnlp.cache.CacheDirectory.getDirStructure(DirectoryNode) is public, it should check the root parameter for null.
> >>>> I would have fixed this myself, but because I have not refactored the code to conform to the XDG specification, I did not want to touch it, while not knowing what to possibly touch as well and hence add perhaps even more damage.
> >>>>
> >>>> To reproduce: Delete %USERPROFILE%.cacheicedtea-webcache or ~/.cache/icedtea-web/cache and then open the cache viewer (perhaps refresh).
> >>>
> >>> Thenx for report. Gave sense. I think I will "force" the creation of  ~/.cache/icedtea-web and ~/.config/icedtea-web at startup.
> >>>
> >>
> >> Ok. There was simple usecase when the directories were not esured. Fixed by this patch.
> >>>
> >>> J.
> > 
> > It's almost working. Only %USERPROFILE%.cacheicedtea-web or ~/.cache/icedtea-web gets created. It is neccessary to create all parent folders too. Please note that currently IcedTea-Web's default cache folder is %USERPROFILE%.cacheicedtea-webcache ~/.cache/icedtea-web/cache. I do not know whether this is desired, since it is a kind of tautology.
> > The problem is that when NetX is run for the first time the default cache folder is already setup although it may not exist. It should get created either when setting up the cache folder on the cache tab is done or at least when the OK button is pressed, perhaps even earlier when the cache tab is selected so that opening the cache viewer does not break anything.
> > 
> > +        File f1 = new File(Defaults.USER_CONFIG_HOME);
> > +        File f2 = new File(Defaults.USER_CACHE_HOME);
> > 
> > Another nit: Please give those local variables some meaningful names like cacheDirectory and configDirectory for better readability.
> 
> ook O:)
> > 
> > Jacob
> > 
> 
> Looks like issue is a bit more widespread. What do you think now?

Looks good. Just one other thing:

+            File f = new File(value);
+            if (f.exists()) {
+                if (JNLPRuntime.isDebug()) {
+                    System.out.println("OK: key " + key + " value: " + value + " exists");
+                }
+                continue;
+            }
+            if (!f.mkdirs()) {
+                if (JNLPRuntime.isDebug()) {
+                    System.out.println("ERROR: key " + key + " value: " + value + " not existed, and was NOT created");

This text should probably be written to stderr.

+                }
+            } else {
+                if (JNLPRuntime.isDebug()) {
+                    System.out.println("OK: key " + key + " value: " + value + " not existed, and was created");
+                }
+            }

If the folder is a file that already exists, the folder in which the folder is created is write protected or the current user has no permission to write to it, or the path is for some reason not available (e.g. failed network connectivity) this circumstance is not handled gracefully and the user is not notified that his/her configuration cannot be saved. All that a user will get is a possibly cryptic exception on stderr that some value or property cannot be saved when clicking OK. The exact same exception pops up when the .cache folder could not have been silently created and then the cache viewer is opend. This is similar to the backup problem.

This may seem as nit picking, but it actually adds greatly to the usability of the application in case of an error or unusual system configuration.

Nevertheless, thank you for addressing this issue, so please keep up the good work.

Regards,
Jacob



More information about the distro-pkg-dev mailing list