329 Lotus blogs updated hourly. Who will post next? Home | Downloads | Events | Jobs | Twitter | Bookmarks | Pods | Blogs | Search | myPL | About 
 
Latest 7 Posts
Mapping Document Collections To Views | Blog
Thu, Apr 11th 2013 232
Making Google Apps For Business Behave Like a Mail Client | Blog
Wed, Apr 3rd 2013 217
Documenting Your LotusScript Classes | Blog
Wed, Mar 27th 2013 278
The Perfect Desk Quest - 2013 Update | Blog
Tue, Mar 26th 2013 241
Updating Glyphicons in Bootstrap | Blog
Thu, Mar 21st 2013 213
Easy Access to Sub-Collections of the DocumentWrapper Class | Blog
Wed, Mar 20th 2013 167
Easy Access to Sub-Collections of the DocumentWrapper Class | Blog
Wed, Mar 13th 2013 191
Top 10
The Hidden Cost of Holidays | Blog
Thu, Jun 14th 2012 838
Laplets are the Way Forward | Blog
Thu, Dec 20th 2012 718
How To Remove Voice Command From Galaxy S2 Without Rooting | Blog
Tue, Jul 10th 2012 602
How Well Do You Know LotusScript? | Blog
Wed, Jan 30th 2013 554
Are Notes Views Still Relevant? | Blog
Tue, Feb 19th 2013 520
Super Useful Set of LotusScript Wrapper Classes | Blog
Mon, Feb 4th 2013 423
How to Do Infinite Scrolling in Domino | Blog
Wed, Mar 6th 2013 421
Be Careful With Custom HTML Attributes (Dojo) | Blog
Mon, Dec 10th 2012 418
Infinite Scrolling Views in Domino | Blog
Thu, Feb 21st 2013 396
Tip: Confirm All Destructive or Irreversible Actions | Blog
Tue, Nov 20th 2012 379


Solution to Java Applet Puzzle | Blog
   

Here's the explanation and the solution to the Java applet issue I mentioned yesterday.

As you saw the page combined a Domino Java View applet and an ActionBar applet. They are two separate applets. They talk to each other using JavaScript. You can see how by looking at the source to the page.

Clicking the Refresh button on the applet calls this JavaScript function:

function Action1_onClick() {
 document.applets.view.refresh();
 return false;
}

That code is calling an exposed method of the View applet called "refresh()". And it's failing. Why?

Well, having isolated the issue to the Java code I needed to get to see the Java console in the hope that any errors were dumped there.

I'd previously told Java not to add an icon to the Task Tray in Windows. If you do see the Java icon down there you can right click it and choose "Show Console".

After some digging I found out how to get to see the Java console. All you do is go to the Control Panel, open the Java options from there and make sure the following options are selected:

image

Next time you open the webpage with the Applets you should see the console appear and start logging, like so:

image

If it appears but with less logging detail, focus on the console and press "5" to set the logging level to verbose and reload the page.

With the console on display I then pressed the Refresh button again and "thankfully" saw an error, as below:

network: Connecting http://www.codestore.net/apps/applets.nsf/view?ReadViewEntries&PreFormat&Start=2.1&Navigate=15&Count=40&SkipNavigate=32784&SkipCount=2 with proxy=DIRECT

An error occurred while reading in documents: java.security.AccessControlException: access denied (java.net.SocketPermission 63.254.226.99:80 connect,resolve)
java.security.AccessControlException: access denied (java.net.SocketPermission 63.254.226.99:80 connect,resolve)
                at java.security.AccessControlContext.checkPermission(Unknown Source)
                at java.security.AccessController.checkPermission(Unknown Source)
                at java.lang.SecurityManager.checkPermission(Unknown Source)
                at java.lang.SecurityManager.checkConnect(Unknown Source)
                at sun.plugin2.applet.Applet2SecurityManager.checkConnect(Unknown Source)
                at java.net.Socket.connect(Unknown Source)
                at sun.net.NetworkClient.doConnect(Unknown Source)
                at sun.net.www.http.HttpClient.openServer(Unknown Source)
                at sun.net.www.http.HttpClient.openServer(Unknown Source)
                at sun.net.www.http.HttpClient.<init>(Unknown Source)
                at sun.net.www.http.HttpClient.New(Unknown Source)
                at sun.net.www.http.HttpClient.New(Unknown Source)
                at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
                at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
                at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
                at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
                at lotus.notes.apps.viewpanel.ViewPanel.postUNIDList(Unknown Source)
                at lotus.notes.apps.viewpanel.ViewPanel.postUNIDList(Unknown Source)
                at lotus.notes.apps.viewpanel.ViewPanel.ReadAndParseViewEntries(Unknown Source)
                at lotus.notes.apps.viewpanel.ViewPanel.ReadLineRange(Unknown Source)
                at lotus.notes.apps.viewpanel.ViewPanel.refresh(Unknown Source)
                at lotus.notes.apps.viewpanel.ViewPanel.refresh(Unknown Source)
                at lotus.notes.apps.viewpanel.ViewPanel.deleteMarkedDocuments(Unknown Source)
                at lotus.notes.apps.viewapplet.ViewApplet.deleteMarkedDocuments(Unknown Source)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                at java.lang.reflect.Method.invoke(Unknown Source)
                at sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
                at sun.reflect.GeneratedMethodAccessor7.invoke(Unknown Source)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                at java.lang.reflect.Method.invoke(Unknown Source)
                at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
                at sun.plugin2.liveconnect.JavaClass$MethodInfo.invoke(Unknown Source)
                at sun.plugin2.liveconnect.JavaClass$MemberBundle.invoke(Unknown Source)
                at sun.plugin2.liveconnect.JavaClass.invoke0(Unknown Source)
                at sun.plugin2.liveconnect.JavaClass.invoke(Unknown Source)
                at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$DefaultInvocationDelegate.invoke(Unknown Source)
                at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$3.run(Unknown Source)
                at java.security.AccessController.doPrivileged(Native Method)
                at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo.doObjectOp(Unknown Source)
                at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$LiveConnectWorker.run(Unknown Source)
                at java.lang.Thread.run(Unknown Source)

At this point I'd been trying all kinds of other approaches to debugging this and had spent hours on it. I've never been so grateful to see an error.

What I still didn't get was why the applet could load the view's content on the first page load - this was a major source of confusion.

Why was there an "access control" issue only when it reloads the view!?

After some searching and lots of reading (and lots of red herrings) I found out that since Java 6 reached "Update 22" a new security feature was implemented. The fix meant that any Java applet making a URL connection which was the result of being asked to do so by a JavaScript call had to do so with the same security settings/permissions as the JavaScript itself.

That's when the applet goes all paranoid! In doing so it wants to rule out the chance it's the target of cross-domain security breach.

But again, things are odd here. It's not cross domain. The applets are loaded from the same domain as the web page itself. As are the subsequent calls to the XML data via ?ReadViewEntries! Why does it think it's cross domain.

The next step and the eureka moment was in working out how the applet decides if it's cross domain or not.

It all comes down to whether or not a "reverse DNS lookups" of the resolved IP address points to the same domain name as shown in the address bar.

To work this out you first need to ping the domain in use, like so:

image

The ping the resolved IP address directly while including the "-a" parameter (resolves addresses to hostnames), as below:

image

Et voila! A reverse DNS lookup for codestore.net points to something completely different! That is why the Java applet breaks!!

To corroborate this I further tested in my own local network on my server called "dover" and resolvable in DNS both as dover and as dover.rockalldesign.com.

I then tried using the applets at the following URLs:

  1. http://dover/apps/applets.nsf/view
  2. http://dover.rockalldesign.com/apps/applets.nsf/view

The Refresh button worked on the first URL but not the second. Why? Consider the following:

image2

On my local network a Reverse DNS Lookup for "dover.rockalldesign.com" doesn't match the expected name of "dover", so the 2nd URL fails. But as you can infer from the above a reverse lookup for "dover" does returns a matching name, so the Java applet is happy to continue loading for the 1st URL.

Solution

The obvious solution would be to make sure you used a domain name in your URL with matches the one returned by a reverse lookup. In the actual customer's case this was a viable solution, as it is for my dover server. But not for the codestore.net version as the mcleodusa.net address it points back to can't be resolved in the address bar.

The alternative (and probably the better) solution is to add a cross-domain.xml file at the root of the HTTP server, so it would be accessible at http://www.codestore.net/cross-domain.xml. The content of the file is simply:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
 <allow-access-from domain="*"/>
</cross-domain-policy>

This will let you access the database using any domain / host which points to the server.

Summary

My customer's response was "Jake, you're a genius!". Well, as much as I'd love to agree, I wouldn't go quite that far. All I am is a patient nerd with enough experience of computers to know how to second guess them. Some times with problems like this it's down to a simple combination of experience and gut instinct.

The fact it's only going to affect users of the Domino View Java Applets made me wonder if it's even worth sharing this (who in their right mind still uses them?!). But then the fact I was asked and then paid to solve it in the first place means people obviously still must use them.

Click here to post a response



---------------------
http://www.codestore.net/store.nsf/unid/BLOG-20120504-0224
May 04, 2012
172 hits



Recent Blog Posts
232


Mapping Document Collections To Views | Blog
Thu, Apr 11th 2013 4:00a   Jake Howlett
It's now a couple of months since I wrote about a Super Useful Set of LotusScript Wrapper Classes, which I've written about on and off since February. Today I want to share a few more extensions I've made to them, which help massively when it comes to getting documents from views. Imagine the following use scenario: Dim factory As New CustomerFactory() Dim coll As CustomerCollection 'Let's get a collection from a view Set coll = factory.GetAll() 'Or you could to this Set coll = factory [read] Keywords: domino lotusscript notes database
217


Making Google Apps For Business Behave Like a Mail Client | Blog
Wed, Apr 3rd 2013 4:16a   Jake Howlett
So, I mentioned that I've moved to a new PC and, for the first time in years, I didn't install a dedicated Mail client/app. Instead I'm using direct web access to Google Apps For Business (posh name for paid-for Gmail). The one thing I never liked about using Email in a browser is that I constantly close and re-open the browser. Thus, in effect, closing my email client, which I then have to remember to re-open. Now though I've made it seem like a real app. You can do this using Chrome's "a [read] Keywords: application email google
278


Documenting Your LotusScript Classes | Blog
Wed, Mar 27th 2013 4:00a   Jake Howlett
Just a quick LotusScript tip: Hopefully you've been inspired by my recent adventures in creating custom LotusScript classes. If so, you'll have noticed that, when creating your own properties and methods in these classes that they get their own comments added in. For example, if you type "property get foo as string" and then press return, you'll see something like this:%REM Property Get Foo Description: Comments for Property Get %END REM Property Get Foo As String End Property Domino De [read] Keywords: domino lotusscript properties
241


The Perfect Desk Quest - 2013 Update | Blog
Tue, Mar 26th 2013 6:20a   Jake Howlett
It must be time for another update on how my desk is evolving towards the elusive "perfect desk". Previous updates here. Here's my desk now, following a recent overhaul: The two main differences from before: The Lenovo T400 laptop and its docking station have gone and the left-most monitor has moved positions to be on the right. My desk needs to not only keep up with the way I work, but also the changes of the times. I decided it was time I got "with the times" and "embrace the cloud" an [read] Keywords: domino lotus notes database development email laptop microsoft office outlook server vm
213


Updating Glyphicons in Bootstrap | Blog
Thu, Mar 21st 2013 4:00p   Jake Howlett
Using Bootstrap, whenever I want to an icon to an element, I simply write HTML like this: Add New And I get something like this: The choice of icons is documented here and the icons themselves are based on Glyphicons "halflings". All is good. However, recently I found myself wanting to use an icon to show that a document had some attachments. Naturally, I wanted a paperclip. Just like a magnifying glass denotes searching, a paperclip denotes a file attachment. Who knows why! To my sur [read] Keywords: css twitter
167


Easy Access to Sub-Collections of the DocumentWrapper Class | Blog
Wed, Mar 20th 2013 12:30p   Jake Howlett
My favourite feature of the Wrapper Classes I keep going on about is the ready access they can give to any given class's related sub-classes. For example, let's say you have an object based on the Customer class and you want to find all their Invoices. Wouldn't it be nice to write code like this in a WQO agent:Dim customer As Customer, invoice As Invoice Set customer = New Customer(web.document) If customer.Invoices.Count > 0 Then Set invoice = customer.Invoices.getFirst() While Not i [read] Keywords: agent properties




191


Easy Access to Sub-Collections of the DocumentWrapper Class | Blog
Wed, Mar 13th 2013 4:20a   Jake Howlett
My favourite feature of the Wrapper Classes I keep going on about is the ready access they can give to any given class's related sub-classes. For example, let's say you have an object based on the Customer class and you want to find all their Invoices. Wouldn't it be nice to write code like this in a WQO agent: Dim customer As Customer, invoice As Invoice Set customer = New Customer(web.document) If customer.Invoices.Count > 0 Then Set invoice = customer.Invoices.getFirst() While Not [read] Keywords: agent properties
225


Creating New Documents Based on the DocumentWrapper Class | Blog
Mon, Mar 11th 2013 7:20a   Jake Howlett
So far, we've seen how to "wrap" an existing document inside a custom class, which is based on the DocumentWrapper subclass. But the document we wrap doesn't have to exist. We can use the DocumentWrapper classes to handle creation of new documents. Imagine that, anywhere in your LotusScript, you could write this: Set invoice = New Invoice(web.database.CreateDocument) invoice.Number = factory.GetNextInvoiceNumber() invoice.Value = 12345.98 invoice.Save() Wouldn't that be cool!? It's quite [read] Keywords: lotusscript database properties
369


Extending The LotusScript Wrapper Classes | Blog
Fri, Mar 8th 2013 3:03a   Jake Howlett
The wrapper classes I blogged about in February went down a lot better than I thought they might. So, taking it further. Let's extend the DocumentWrapper class some more. Since first writing about them  on here I've been busy using and extending them as I go. Here are a few examples of some of the properties I've added Simple Helper Properties Some very simple properties: WebLink, UNID and IsNew. Property Get WebLink As String WebLink = "/" + Replace(web.database.Filepath, "", "/" [read] Keywords: domino lotusscript database properties
421


How to Do Infinite Scrolling in Domino | Blog
Wed, Mar 6th 2013 3:00a   Jake Howlett
Last week I linked to a Domino-based infinite-scrolling view demo and promised I'd write up how I did it. Even though the reaction to the demo was mixed I'm a man of my word, so here goes. It always surprises (worries!) me when I'm asked to either share a downloadable copy of a demo or write a how-to about it. Particularly when it's something that's all but completely web-based. The code is there to see; just a click away. That said, in this case, unless you're familiar with jQuery and/or [read] Keywords: agent domino lotusscript notes ajax application development server




Created and Maintained by Yancy Lent - About - Blog Submission - Suggestions - Change Log - Blog Widget - Advertising - Mobile Edition