EGL Development User Group - Group home

A handful of frequently asked questions on rich web development

By Jiyong Huang posted Wed April 01, 2020 09:18 PM

When you are developing EGL Rich UI (RUI) applications, you are really developing distributed web applications. EGL never tries to replace existing frameworks or standards, such as HTML, CSS, REST/SOAP, and application servers. We just try and make using all this plumbing a lot easier to consume by people like you.  

While EGL solves much of the complexity surrounding web development, to be most effective in your job you should know a little bit about the underlying frameworks and solutions that the web offers, and that RUI uses and simplifies.

Below, you will find a list of Q&A's that discuss topics that many of you run into and may actually have wondered about already.

What security features are available in RUI?

The Internet is a scary place. Many attack vectors are available such as malicious script execution, cross-site scripting, dynamic generation/execution of scripts and denial of service attacks. EGL Rich UI is a technology that is simply a very thin veneer on top of JavaScript. It gets compiled into JavaScript and gets linked with an EGL runtime that is hand-written in JavaScript. When you deploy your end result and run it in a browser, you are really running a JavaScript application. This means that all questions surrounding security in EGL Rich UI come down to "what security features are available in JavaScript?"

RUI cannot offer more security than whatever is offered in JavaScript, which is pretty much minimal. To protect sensitive applications, you would have to completely control the browser and disallow any extensions or addons to be installed. That would minimize the risk of unknown code being inserted at the user's end. Today, I checked my browser, which has the "StumbleUpon" extension added to it. The following code was loaded in my browser session:

// everypage_early.js
// This content script gets injected into every page, enabling
// us to inject the StumbleUpon lite toolbar into the DOM
// of the page.

Another mechanism to insert extra code could be by intention. People routinely use third party widgets, such as page counters, or things like Google Maps. To run those gadgets in your application you are essentially downloading and running third party code inside your application without being able to completely ensure they are not scanning the heap or extracting cookies from your browser store. If you are serious about this, never include third party code unless you have access to the source or know and trust your provider. Some applications go as far as detecting if they are being loaded in an iFrame, and disallow that, for instance.

Reeingineering web apps is child's play, as the JavaScript is in plain sight. Anyone can see the code, read it, and change it before it runs.

Another attack could be the "man in the middle". Code, or data, that is downloaded from a server can be intercepted by malicious parties, and extra code can be inserted along the way to run inside your browser as a trojan horse. Using secure socket connections, which establish a private peer-to-peer connection between your browser and server certainly minimize the risk of code insertion.

Finally, hackers or inside agents can get control of your server through a different attack (or login), and replace your application's code with newly enhanced code.

Concluding, minimize third party libraries to those you trust, avoid the use of addons/extensions, use SSL, constantly update your browsers, and DO NOT USE IE6!

Which features of Open Ajax Hub 2.0 are supported by RUI?

The prime objective of the Open Ajax Alliance is to accelerate customer success with Ajax by promoting a customer's ability to mix and match solutions from Ajax technology providers. The OpenAjax Hub solution offered in EGL is based on version 1.0. The entire implementation is done in an EGL library with one external type. It's not a lot more than say 20 lines of EGL. You can find out more about its API by hitting F1 inside RBD/EGL CE and search for InfoBus.

Version 2.0 was experimental when we release EGL Rich UI, and we will consider picking up the extra features offered in v2.0 in future releases of RUI.

What support for data encryption exists for cached data on the client side in RUI?

All browsers uses caching to improve the loading time of frequently used JavaScript and webpages (static content). This includes the EGL code that gets translated into JavaScript. To store and cache data on the client, cookies or browser-local storage can be used.

There are a few mechanisms for client-side data storage, none of which have encryption built in. Cookies are key-value pairs that are made accessible to the current browser and are controlled per browser domain. Any code running in the session has access to these cookies.

Brower-local storage in HTML5 and Google Gears provides similar storage, with either key-value pairs, or a full SQL API. Each domain+port number combination gets its own database to control the access. It is not possible to access the database from another browser session. However, it is possible to track down the database on the file system, and extract the data from there, of course. Encryption of the data would have to happen in JavaScript code, which brings us back to the first question in this list. If you use encryption, the algorithm and encryption keys will be visilble at some point to any trojan horse in your application.

Do not store sensitive data in client-side storage. For instance, do not load complete credit-card numbers, but just the last 4 digits so that a user can identify it.

Is it possible to securely move business logic to client side for execution?

It is best to keep sensitive business logic on the server, make it use authentication and security. It will be interacting with other services, databases and performing complex operations. Code that checks to see if a social security number is valid can never be run from the browser. Code that embodies the IP of your company or institution should be kept away from prying eyes also. The browser is ideal for presentation of data, navigation, drill-down, filtering, composition, and input validation. It is not a good place for computing mortgage rates, or doing complex portfolio analysis. You can check whether an email address is syntactically correct to make the end-user more productive. However, to see if the email address is already in use, you really have to run server code.

What does the RUI/web 2.0 application lifecycle look like?

A RUI application is different from a web 1.0 application, such as JSF. In web 1.0, the user navigates through a set of pages. The server creates the entire page, including all the HTML, CSS, and JavaScript needed to show the result in the browser. When a user click on a link, the page refreshes the entire browser window. The server is aware of exactly at what page you are now, and keeps a large state to support your application. In fact, your web page is really an application that is running on the server, not in the browser. This is why Tomcat and WAS are called application servers.

In a RUI application the page is loaded only once as a static, and cacheable, HTML file. Once the file is loaded into the browser, JavaScript is used to load only what the user needs to continue using the application. The entire UI is created by making DOM operations on the currently loaded document. This methodology allows the application to feel more like a standard desktop application.

A RUI application is an event-driven application. There are three main event types in a web2.0 application:

  • Browser events such as keyboard and mouse events. Any widget can capture any event and handle it in an EGL function. Typically, the DOM is modified (other widgets are created or their attributes are modified) or a service call is made to request some data from a server.

  • Service calls return from the server. A user-provided callback is invoked, and the DOM is modified or more service calls are made.

  • A timer goes off. RUI has the notion of "jobs" to manage repetitive or delayed actions to be executed in the browser.

All events end up in an event queue in the order they are received. Only one single thread runs in the browser, and it runs the top of the queue. While it is running the top event, nothing gets rendered in the browser. Numerous changes can be made to the DOM, and the browser keeps track of them all. But, only when the thread returns is the browser content rendered to show all the modification being made while the event was being dealt with. If another event is waiting, it gets processed in the order it was received. This loop continues ad infinitum.

As the browser is single threaded, execution has to happen asynchronously and any operation that takes a while to complete needs to be broken up in various sub-activities to avoid making the browser unresponsive.

Is there support for other third-party widgets apart from dojo widgets?

Yes, RUI supports anything that has a JavaScript API, and that includes any kind of third-party widget library. The Dojo widgets are a great example about how someone could quickly create a widget library. Widgets are exposed through so-called ExternalTypes, which define the EGL type bindings for the JavaScript APIs. Examples exist that use Google maps, JQuery, Flex, Flash, SilverLight, GWT, etc, etc.

What mechanisms are available to measure the performance of each widgets at runtime (logging/instrumentations)

As said above, EGL gets compiled into JavaScript. To measure performance, it is best to use a profiling tool that is integrated into the browser. Firefore + Firebug works really well. IE8 has a really good profiler that we used to analyze Grid performance and led us to improve its performance by 20X. Just hit F12 to activate it. Chrome also has a really nice profiler built in, activated by Ctrl-Shift+J.

Instrumentation can also be used. During development, the EGL tooling inserts egl.enter and egl.leave calls for each single function. It is not too hard to intercept those calls and do some time measurement there. However, the Heisenberg uncertainty principle applies. By measuring time this way, you will change how the code is running and taint the results.

Web 2.0 applications are intrinsically asynchronous, and a web application can look slow simply because it is waiting on a service call to return. To measure services, EGL CE comes with a service monitor (check out the Dojo package). In RBD, you can install the dojo package from the EGL Cafe, or read the Major Tom article.

As services run asynchronously, you should always present visual feedback directly, and then kick off the service. Once the response comes back, you can replace the earlier message with new feedback.

Are the Dojo widgets available in RBD

You can definitely use the Dojo widgets in RBD The current version of the Dojo widgets are available on the Cafe in 0.7.1. That said, we are getting ready to release version 0.8 of the EGL Dojo Widgets based on Dojo 1.4 April 30th on the Cafe. All you would need to do is download the project interchange file from the EGL Cafe and import it.

When creating a library there’s an RichUI properties library option, what’s this?

This question is a variation on "How does RUI support I18N?". The Rich UI properties library is used to bind application level message to the currently chosen browser locale. An application can support multiple locales, and depending on which locale the user selected, messages are printed in different languages using a lookup table provided in a properties files.

In JSF we have request,session and application variables how to handle this in RichUI?

In RUI, the state is kept in the browser. The server knows very little, if nothing about your state. Say you have a shopping application. In JSF, the entire shopping cart is kept on the server, and things are added and removed by changing the state on the server. This reduces the scalability of the server as it needs to allocate quite some memory to store all this state. In the case of RUI, the entire shopping cart is in the browser. Modification are done in the client. Only when you check out, the entire shopping cart is sent to the server, with your credentials, and at that point the state gets transferred to the server, it does its things, updates some databases, and clears its state again. This makes the server much more scalable as a result, as it moves state/control from the server to the browser.

How do I include a CSS file that is shared by more than one project, such as a company-wide global stylesheet?

EGL organizes its code in RUI handlers, which are contained in packages, which are part of a project. A project can depend on other projects, and that generates the so-called EGL Build Path. If project B depends on project A, anything exported by project A can be seen by project B. This allows you to define reusable components, store them in a project, and reuse them in multiple projects. In fact, the RUI runtime project is designed just like that. So is the Dojo widgets project.

In the editor's "design" tab, can I use the outline view to arrange widget layout, instead of dragging and dropping in the visual editor canvas?

The visual designer allows you to drag and drop widgets from the palette directly to the outline view. You can also interact with the outline view to rearrange the widgets, and delete one or more of them.

Can I include things like <meta> tags in my generated HTML file?

The EGL tooling generates the HTML files as part of its deployment step. To modify the generated HTML, you would have to write a script to edit the generated HTML, or use an Ant script such as described in this blog entry. The same technique is used by the iPad application described in this blog entry.

What happens at runtime when the children field is set? What is the life-cycle of widgets and RUIHandlers?

When you set the children field on a Box, for instance, you don't just set the field. In the IDE, select the children field, and hit F3. This will take you to the defintion inside Box.egl. You will see that the field is declared as an EglProperty. This means it has getter and setter methods. Inside the setChildren method, we create a new table, with rows and cells to hold the children you just added. If at some point later you add another widget to the children array, nothing will happen, as that won't trigger the setter. You can say something like box.children=box.children, or say box.layout() to force a new layout.

The EglProperty annotation can be used on any field you declare in your own RUIHandlers also. It is great for implementing side effects where you really want to have a declarative API to construct objects. ExternalTypes have a similar annotation, called JavaScriptProperty.

How can I handle window.onClose events?

The History support in RUI allows you to keep a user on the same page by asking them if they really want to leave, or first save their work. If you want to control the life cycle of DOM elements in other ways, it is very easy to write your own external type to expose the events. Just follow the implementation of HistoryHelper and its accompanying .js file in the WebContent folder of the rui widgets project for an example.

Does RUI support any type of workflow?

RUI has no workflow engine built into it, other than using the InfoBus for decoupling components and controlling visibility and activation based on what events are broadcasted by other component. RUI does come with an MVC implementation that helps manage separating concerns between models and views, but this is still a limited control flow example.

Depending on the kind of workflow your looking for, Lotus and Websphere provide workflow engines for describing the overall communication between servers and clients.

Can a user safely cancel a long running action in RUI?

As RUI applications do most of their real code on the server, this question boils down to "how do I implement transactions in a distributed web application?". EGL and RUI have no specific solution for this, nor does any other web 2.0 framework. This is really an application-level feature. Because operations are asynchronous, you really need to implement something like double-commit. This is what happens when you buy books at Amazon, for instance. Once you press the button that says "add to cart", you still have not bought the book. Even when you checked out, did you buy the book? No. Only when you get the confirmation from Amazon saying that the sell has been confirmed, did you buy the book. If you change your mind at that point, can you cancel the purchase? Sure. If you already received the book at home, things get more complex, of course. But, what his patterns tells us is that web applications need support for "undo".

For a while, gmail had a special feature to "unsend" email you sent out. There was a certain time within which gmail held on to the emails, and you could change your mind. Last time I checked, that feature is now removed. Same goes for those images you post on Facebook.

If you implement transactions in your web application, you should support unreliable communications, and assume people abandon their shopping cart in mid-air.

Does RUI have support for Aspect Oriented Programming (AOP) techniques?

Aspect-oriented programming uses techniques such as mixins to add extra behavior to existing code without complicating the original implementation of the widgets. RUI has such support in its Grid, Menu, MVC and Tree widgets. Those widgets have the ability to add new concerns with behaviors, formatters, and validators using EGL code or declarative annotations. This reduces complexity and makes your code much more flexible. As a whole AOP is not a focus for RUI and EGL does not have support for weaving in different concerns. This is a very exciting area though, and we definitely expect people to experiment in this area once the EGL Open project goes live where you will have full access to the code generation and parsers for EGL.

Does RUI have support for Views composition (independent modules and views are composed at runtime)?

Independent views/modules can be loaded at runtime by a RUI application. A separate blog entry goes into extensive detail. A RUI application can also be hosted by a solution such as Portal, and use inter-portlet communication.

What communications patterns are supported between components/widgets?

Widgets and rui handlers can call each other directly, if they have a reference to each other. For larger applications, keeping track of all these references becomes laborious and makes the code look like spaghetti. It is better to use the InfoBus, which acts like an application-level whiteboard where message can be published without any handler explicitly needing to know others. Handlers can subscribe to the infobus using filters encoded with path expressions and wild cards.

If you have any more questions, append them as a comment to this blog entry.