Thread: [Openjnlp-devel] New OpenJNLP User / Some Patches
Brought to you by:
kherr
From: Nathan M. <nm...@vi...> - 2002-11-19 12:23:30
|
Hello OpenJNLP Community, I'm a new user of OpenJNLP. It solves an important problem for me - thanks for a valuable contribution to the JNLP world! I'm using OpenJNLP 0.7 in an environment it's never encountered before: running an application launched with an URL containing query fields. For example: http://myhost/myapp?foo=bar&baz=foo My environment exposed some OpenJNLP bugs - I've attached some patches to address them. Here's a brief explanation of the problems and patches: - IconFactory.java contains an extraneous semicolon that causes compilation to fail with some compilers; it creates an "unreachable statement". - JNLPContentHandler fails to set the resource properties when it builds an ApplicationDescriptor. - FileCacheEntry does not properly deal with resource names such as my example URL, above - it creates badly formed XML documents that do not parse. I've added logic to transform the strings stored in "entry.xml" into a form safe to use in an attribute field or as element text: the dangerous characters <>'"& are replaced with character entity codes that will be properly recognized and parsed by XML compilers such as NanoXML. There's one more change I'd like to make. I might not get to it very quickly, but here's the remaining problem I'd like to fix: the library should *not* apply the same caching logic to .jnlp files that it applies to resources specified in the .jnlp files; it should just fetch the URL once and then use it. As is, it's issuing something like four queries (GET and HEAD) against the same URL - in my case causing the server to perform a lot of wasted work. If/when I'm able to fix this one, I'll send more patches. Thanks again for the great work! Nathan Meyers nm...@vi... Index: src/org/nanode/app/openjnlp/desktop/IconFactory.java =================================================================== retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/nanode/app/openjnlp/desktop/IconFactory.java 18 Nov 2002 12:04:16 -0000 1.1.1.1 +++ src/org/nanode/app/openjnlp/desktop/IconFactory.java 18 Nov 2002 13:30:21 -0000 1.2 @@ -150,7 +150,7 @@ * @see #getIcon(Descriptor, String, int) */ public static ImageIcon getIcon(Descriptor des, int size) { - return getIcon(des, Information.ICON_DEFAULT, size);; + return getIcon(des, Information.ICON_DEFAULT, size); } /** Index: src/org/nanode/jnlp/JNLPContentHandler.java =================================================================== retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/nanode/jnlp/JNLPContentHandler.java 18 Nov 2002 12:04:17 -0000 1.1.1.1 +++ src/org/nanode/jnlp/JNLPContentHandler.java 18 Nov 2002 21:52:01 -0000 1.2 @@ -533,6 +533,10 @@ for (Iterator iter = nativelibSet.iterator(); iter.hasNext();) { resources.addReference((Reference) iter.next()); } + + if (props != null) { + resources.setProperties(props); + } descriptor.setContext(jnlpSpec); descriptor.setInformation(information); Index: src/org/nanode/launcher/cache/FileCacheEntry.java =================================================================== retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/nanode/launcher/cache/FileCacheEntry.java 18 Nov 2002 12:04:19 -0000 1.1.1.1 +++ src/org/nanode/launcher/cache/FileCacheEntry.java 18 Nov 2002 18:51:51 -0000 1.2 @@ -510,7 +510,7 @@ fw.write(" <meta name=\""); fw.write(key); fw.write("\">"); - fw.write(entryMeta.getProperty(key)); + fw.write(xmlEncode(entryMeta.getProperty(key))); fw.write("</meta>\n"); } @@ -524,7 +524,7 @@ fw.write(" <resource href=\""); } - fw.write(rsrc[i].getReference().getURL().toString()); + fw.write(xmlEncode(rsrc[i].getReference().getURL().toString())); fw.write("\" modtime=\""); fw.write(Long.toString(rsrc[i].getLastModified())); fw.write("\" />\n"); @@ -539,6 +539,27 @@ } catch (Exception e) { System.err.println(e); } + } + + /** + * Render a string safe for use in an attribute or element text + * in an XML document. The result should be fully parsable by + * an XML parser. + */ + public static String xmlEncode(String xml) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < xml.length(); i++) { + char ch = xml.charAt(i); + switch (ch) { + case '<': result.append("<"); break; + case '>': result.append(">"); break; + case '"': result.append("""); break; + case '\'': result.append("'"); break; + case '&': result.append("&"); break; + default: result.append(ch); break; + } + } + return result.toString(); } /** |
From: Nathan M. <nm...@vi...> - 2002-11-19 16:42:25
|
Just a brief followup to my note from earlier today: I hope you can use the patches I sent in my earlier email. Please apply them *directly from the email* - do not cut/paste them from the copy of the email in the SourceForge mail archives! The Java source is corrupted during the processes of rendering the mail viewable to browsers. Nathan Meyers nm...@vi... |
From: Kevin H. <ke...@na...> - 2002-11-19 17:17:38
|
On Tuesday, Nov 19, 2002, at 06:23 US/Central, Nathan Meyers wrote: [...] > My environment exposed some OpenJNLP bugs - I've attached some patches > to address them. Here's a brief explanation of the problems and > patches: Thanks for the patches. (After too long of an absence from working on OpenJNLP) I was about to start work on a minor point release to fix a couple of bugs. I'll look at incorporating your patches. [...] > There's one more change I'd like to make. I might not get to it very > quickly, but here's the remaining problem I'd like to fix: the library > should *not* apply the same caching logic to .jnlp files that it > applies > to resources specified in the .jnlp files; it should just fetch the URL > once and then use it. As is, it's issuing something like four queries > (GET and HEAD) against the same URL - in my case causing the server to > perform a lot of wasted work. If/when I'm able to fix this one, I'll [...] Have you tried this with Java Web Start? It behaves in pretty much the same fashion. The real answer, I believe, is to improve the implementation of caching. I have been planning to look at implementing "If-Modified-Since" logic so only a single request to the server needs to be made. |
From: Nathan M. <nm...@vi...> - 2002-11-19 18:05:51
|
On Tue, Nov 19, 2002 at 11:17:32AM -0600, Kevin Herrboldt wrote: > >There's one more change I'd like to make. I might not get to it very > >quickly, but here's the remaining problem I'd like to fix: the library > >should *not* apply the same caching logic to .jnlp files that it > >applies > >to resources specified in the .jnlp files; it should just fetch the URL > >once and then use it. As is, it's issuing something like four queries > >(GET and HEAD) against the same URL - in my case causing the server to > >perform a lot of wasted work. If/when I'm able to fix this one, I'll > [...] > > Have you tried this with Java Web Start? It behaves in pretty much the > same fashion. The real answer, I believe, is to improve the > implementation of caching. I have been planning to look at implementing > "If-Modified-Since" logic so only a single request to the server needs > to be made. Thanks for the response, Kevin. I don't see how improving the cache implementation helps. To say that you're caching something implies making an initial HEAD request to decide whether to do a GET - a win for resources that are large and reasonably static, a loss for everything else. In my case, it's a big loss for the startup .jnlp document. And if you only do a GET, why bother caching a result you'll never need again? Nathan Meyers nm...@vi... |
From: Kevin H. <ke...@na...> - 2002-11-19 18:23:37
|
On Tuesday, Nov 19, 2002, at 12:05 US/Central, Nathan Meyers wrote: [...] > I don't see how improving the cache implementation helps. To say that > you're caching something implies making an initial HEAD request to > decide > whether to do a GET - a win for resources that are large and reasonably > static, a loss for everything else. In my case, it's a big loss for the This is true if the caching mechanism is HEAD+GET. I should have been clearer. I was thinking of switching the caching over to GET only using the "If-Modified-Since" HTTP header, which should cause the server to only send the contents of the requested resource if it's newer than that header. This effectively turns GET into a HEAD request if OpenJNLP has an up-to-date resource. There are admittedly some issues with the logic of OpenJNLP and how it parses JNLP files. There must be at least one too many attempts to load the JNLP file. > startup .jnlp document. And if you only do a GET, why bother caching a > result you'll never need again? I'm not sure if you know this about JNLP, but if you don't want a JNLP file cached you make sure the <jnlp> tag does not have an href attribute. Somewhere in the JNLP specs this is documented, although it's obscure. |
From: Nathan M. <nm...@vi...> - 2002-11-19 20:14:00
|
On Tue, Nov 19, 2002 at 12:23:32PM -0600, Kevin Herrboldt wrote: > On Tuesday, Nov 19, 2002, at 12:05 US/Central, Nathan Meyers wrote: > [...] > >I don't see how improving the cache implementation helps. To say that > >you're caching something implies making an initial HEAD request to > >decide > >whether to do a GET - a win for resources that are large and reasonably > >static, a loss for everything else. In my case, it's a big loss for the > > This is true if the caching mechanism is HEAD+GET. I should have been > clearer. I was thinking of switching the caching over to GET only using > the "If-Modified-Since" HTTP header, which should cause the server to > only send the contents of the requested resource if it's newer than > that header. This effectively turns GET into a HEAD request if OpenJNLP > has an up-to-date resource. Thanks for the clarification. Yes... this makes sense. > There are admittedly some issues with the logic of OpenJNLP and how it > parses JNLP files. There must be at least one too many attempts to load > the JNLP file. > > >startup .jnlp document. And if you only do a GET, why bother caching a > >result you'll never need again? > > I'm not sure if you know this about JNLP, but if you don't want a JNLP > file cached you make sure the <jnlp> tag does not have an href > attribute. Somewhere in the JNLP specs this is documented, although > it's obscure. I wasn't aware of this but I don't have that attribute anyway - it doesn't make sense for a dynamically generated page. So it looks like OpenJNLP isn't currently following this practice. Nathan Meyers nm...@vi... |
From: Kevin H. <ke...@na...> - 2002-12-02 19:12:48
|
Just to let everyone interested know... Tuesday, Nov 19, 2002, at 06:23 US/Central, Nathan Meyers wrote: [...] > - IconFactory.java contains an extraneous semicolon that causes > compilation to fail with some compilers; it creates an "unreachable > statement". > > - JNLPContentHandler fails to set the resource properties when it > builds an ApplicationDescriptor. > > - FileCacheEntry does not properly deal with resource names such as [...] These bugs were all fixed in the recent OpenJNLP 0.7.1 release. Nathan's later patch was not included because of timing. It will have to wait for the next release. The changes were done on the ver-0-7 cvs branch and I have not yet merged into the main branch. I'll be doing that shortly and will let this list know when it's done. I'm going to roll off a major project here in a few weeks and will only be working on three things simultaneously so maybe I can devote more energy to OpenJNLP. |