DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Popular Topics

article thumbnail
Top Open Source ESB Projects
In today's software markets, open source technologies are giving commercial products some stiff competition. Enterprise Service Busses are no exception. Don Rippert, the chief technology officer at Accenture says, "ESBs are software products that allow you to create a business process with web services running on different platforms." Rippert believes an ESB is essential for achieveing the full potential of service-oriented architecture. In general, an ESB should provide flexibility built on a basis of standards. Jos Dirksen, an author of "Open Source ESBs in Action," said in a recent interview that today's top open source ESBs were "on par with commercial alternatives." Competition drives innovation, and this page has a list of the most competitive open source ESBs on the market. Here are the the forerunners among open source ESBs (in no particular order): JBoss ESB JBoss JBoss generally has mature components in its GA releases with no vendor-lockin characteristics. Their ESB leverages JEMStechnologies like the JBoss business rules engine for content-basedrouting and messaging. Content-based routing on the JBoss ESB can use Drools or XPath. The JBoss ESB supports XSLT and the Smookstransformation engine for XML and non-XML data formats. JBoss' ESBalso runs on the JBoss application server and features a pluggable architecture for swapping out ESBsubsystems. Apache ServiceMix Apache Apache ServiceMix 4 is OSGi based and a great option for integrating with an XML standards focussed landscape. Apache ServiceMix makes it very easy to hot-deploy new integration flows. Even the pluggable integration components are hot deployable. ServiceMix uses a JBI standard which provides a lot of components like JMS, BPEL, Web service, and Camel. The inclusion of Camel is a strong point for ServiceMix along with the Spring Framework, which is also supported. FUSE ESB is another great distribution of Apache ServiceMix. OpenESB Sun(Oracle) OpenESBhas an easy learning curve due to its solid integration with theGlassFish Application Server and Sun's popular IDE, NetBeans. TheNetbeans IDE provides countless integrated functions for administrationand development. The best thing about OpenESB is its toolset. OpenESB's tools include WSDL and schema editors, a JPI manager integrated into the service manager, and Antrunning in the background. Another tool is the Composite ApplicationService Assembly (CASA) editor, which gives you a graphical overview ofintegration applications. Many Java developers will love OpenESBbecause it comes straight from the home of Java. OpenESB is also OSGi based. MuleESB MuleSoft Mule is the most used open source integration platform. MuleESB's low cost along with easy configuration, expansion, and flexibility make it very popular. Java developers will find MuleESB easy to work with because it is Java centric. There’s also a powerful set of XML schemas in MuleESB. The creation of integration flows is very straightforward. MuleESB can have fairly complex integration flows up and running in minutes. It has many connectivity, routing, and transformation options right out of the box. WSO2 ESB WSO2 Other ESB products take a relatively heavyweight approach by using the JBI specification, but the relative newcomer, WSO2, takes a lightweight approach in its ESB. It does this by focusing on Web service standards for integration. The WSO2 ESB uses Apache Synapse, a nimble Web service mediation and routing engine that focuses on providing fast XML message processing. WSO2 takes advantage of Synapse's non-blocking http://s transport implementation over the Apache HttpComponents/NIO module. This allows the WSO2 ESB to handle thousands of parallel requests using a small amount of resources and threads. You can always expect great XML support from the WSO2 ESB because well-known XML expert James Clark is a company director at WSO2.
October 29, 2009
by Mitch Pronschinske
· 241,461 Views
article thumbnail
JSF 2 GETs Bookmarkable URLs
JSR-314: JavaServer Faces (JSF) 2.0 demonstrates a strong evolution of the JSF framework driven by de facto standards that emerged out of the JSF community and participating vendor's products. This article, the second installment in covering JSF 2.0 features contributed by Red Hat, or which Red Hat participated in extensively, covers the new features that bring formalized GET support to a framework traditionally rooted in POST requests. The primary building blocks of this support are view parameters and a pair of UI components that produce bookmarkable hyperlinks. Both features incubated in Seam and, therefore, should be familiar to any Seam developer. They are also features for which the JSF community has passionately pleaded. Author's Note: Many thanks to Pete Muir, who played a pivotal role as technical editor of this series. Read the other parts in this article series: Part 1 - JSF 2: Seam's Other Avenue to Standardization Part 2 - JSF 2 GETs Bookmarkable URLs Part 3 - Part 4 - Part 5 - Every user session must start somewhere. JSF was designed with the expectation that the user always begins on a launch view. This view captures initial state and allows the user to indicate which action to invoke by triggering a UI event, such as clicking a button. For instance, to view a mortgage loan, the user might enter its id into a text box and then click the "Lookup" button. The assumption that this scenario is the norm is surprising since it overlooks that fact that the web was founded on the concept of a hyperlink. A hyperlink points to a resource (URI), which may already contain the original state and intent, such as to view a mortgage loan summary. There's no need to bother the user with a launch view in this case. While hyperlinks are most often used in web sites, they apply to web applications as well (see this blog entry for a discussion about the difference between a web site and a web application). Hyperlinks support reuse by serving as an exchange language in composite applications. One application can link to a resource in another application in lieu of having to duplicate its functionality. In fact, the request may be coming from a legacy application that isn't even web-based. In that case, you'll likely be plopping the user into the web application somewhere in the middle. As it turns out, this situation is quite common. When you visit a blog, do you start on the search screen to find an entry to read? Not likely. More times than not, you click on a link to view a specific blog entry. The point to take away from this discussion is that initial requests (referred to as non-faces requests in JSF) can be just as important as form submissions (faces requests), whether in a web site or web application. In the past, JSF has struggled to support the scenario cited above, placing much more emphasize on faces requests. JSF 2 rectifies this imbalance by introducing view parameters and hyperlink-producing UI components. View parameters allow the application to respond to a resource request by baking formal processing of request parameters into the JSF life cycle for both GET and POST requests. View parameters are not limited to consuming data. They are bi-directional. JSF 2 can propagate the data captured by view parameters when generating bookmarkable URLs, with complementary behavior for redirect URLs produced by redirect navigation cases. We'll start by examining view parameters, how they are defined and how they are worked into the JSF life cycle. You'll then discover how they work in tandem with the new hyperlink-producing components and the navigation handler to bring "bookmarkable" support to JSF. Introducing view parameters The API documentation describes a view parameter, represented by the javax.faces.component.UIViewParameter component class, as a declarative binding between a request parameter and a model property. The binding to the model property is expressed using an EL value expression (e.g., #{blog.entryId}). If the expression is omitted, the request parameter is bound instead to a request-scoped variable with the same name. Here's a simple example of a view parameter that maps the value of a request parameter named id to the JavaBean-style property named entryId on a managed bean named blog. Assuming the entryId property on the blog managed bean is of type long, a value of 9 will be assigned to the property when the following URL is requested: http://domain/blog/entry.jsf?id=9 But wait, there's more! The value of the request parameter is first converted and validated before being assigned to the model property. This behavior should sound familiar. That's because it mirrors the processing of form input bindings on a faces request. In a way, view parameters turn the query string into an alternative form submission. And like form inputs, view parameters are also processed during faces requests. The complete view parameter life cycle is covered later when we look at view parameter propagation Before going any further, it's important to point out that view parameters are only available when using the new View Declaration Language (VDL), a standardized version of Facelets. The primary reason is because the JSR-314 EG agreed that no new features should be made to support JSP since it's deprecated as a view handler in JSF 2. Perhaps you are thinking... Isn't this already possible? If you are savvy JSF developer, you're perhaps aware that it's already possible to map a request parameter value to a model property. The assignment is declared by referencing an element of the #{param} map in a element of a managed bean declaration. For instance, you could alternatively map the id request parameter to the blog managed bean in faces-config.xml as follows: blog com.acme.Blog entryId #{param['id']} The similiarities end there. View parameters go above and beyond this simple assignment by providing: View-oriented granularity (the property mapping in the managed bean definition is global to the application) Custom converters and/or validators (along with failure messages) Bi-directionality It's hard to say which feature is the most important, but bi-directionality is certainly the most unique. Since view parameters are a mapping to a JavaBean-style property, the value can be read from the property and propagated to the next request using either the query string or the UI component tree state (depending on the type of request). You are going to find out how useful this bi-directionality can be later on in the article. Suffice to say, while the property mapping in the managed bean definition works, it's pretty anemic. View parameters are far more adequate and robust in contrast. Pertaining to the topic in this article, view parameters are the key to bringing bookmarkable support to JSF. And since bookmarks link to specific views, so must view parameters. It's all in the view As you may have guessed, view parameters are view-oriented. That means they somehow need to be associated with one or more views (as opposed to being linked to a managed bean, for instance). Up to this point, however, there was no facility for associating extensible, non-rendering metadata with a JSF view. So the EG first had to find a place within the UI component tree to stick metadata like view parameters. That led to the introduction of the metadata facet of UIViewRoot. The next section will introduce this new facet and how it's used to host view parameters for a particular view, or even a set of views. Then we get into how view parameters get processed in the JSF life cycle. The view metadata facet View parameters provide information about how request parameters should be handled when a view is either requested or linked to. The view parameters are not rendered themselves. Therefore, we say that they are part of the view's metamodel and described using metadata. So the question is, "Where should this metadata live?" It turns out that a JSF view, which is represented at the root by the javax.faces.component.UIViewRoot component class, already accommodates some metadata. Currently, this metadata consists of string values to define settings such as the locale, render kit, and content type of the view, and method expressions that designate view-specific phase observers. For example: ... While values can be assigned to these metadata properties explicitly in Java code, more often they are assigned declaratively using corresponding attributes of the component tag. But neither UIViewRoot or it's component tag can accommodate complex metadata--that is, metadata which cannot be described by a single attribute. That's were the view metadata facet comes in. The view metadata facet is a reserved facet of UIViewRoot, named javax_faces_metadata, that can hold an arbitrarily complex branch of UI components that provide additional metadata for a view. Facets are special because they are ignored by a UI component tree traversal, requiring an imperative request to step into one of them. This aspect makes a facet an ideal candidate for tucking away some metadata for the view that can be accessed on demand. The view metadata facet looks like any other facet in the UI component tree. It must be declared as a direct descendant of within a view template as follows: ... ... Note: If you are using Facelets, you may not be familiar with the tag since it's optional in Facelets. When you add it to your template, it must be the outer-most component tag, but it does not have to be the root of the document. Since the view metadata facet is a built-in facet, and is expected to be heavily used, the alias tag was introduced as a shorthand for the formal facet definition shown above: ... ... We now have a place in the UI component tree to store metadata pertaining to the view. But why define the metadata in the view template? It's all about reuse and consistency. Describing view metadata with UI components There are two important benefits to defining the metadata within the view template. First, it circumvents introducing yet another XML file with its own schema that developers would have to learn. More importantly, it allows us to reuse the UI component infrastructure to define behavior, such as registering a custom converter or validator, or to extract common view parameters into an include template. Since we're using UI components to describe the view metadata, then it makes sense to treat the UIViewParameter like any other input component. In fact, it extends UIInput. That allows us to register custom converters and validators on a UIViewParameter without any special reservations. Here's an example: Note: Later in this series you'll learn that like input components, view parameters can enforce constraints defined by Bean Validation annotations (or XML), making the explicit validation tags such as this unnecessary. But there is one caveat to embedding the view metadata in the template. Without special provisions, extracting the metadata would require building the entire view (i.e., UI component tree). Not only would this be expensive and unnecessary if the intent is not to render the view, it could also have side effects. When the component tree is built, value expressions in Facelets tag handlers get evaluated, potentially altering the state of the system. To prevent these counteractions, the view metadata facet is given special treatment in the specification. Specifically, it must be possible to be extract and built it separately from the rest of the component tree. Earlier, I mentioned that view parameters are only available in Facelets, and not JSP, because of an executive decision. There's also a technical reason why view parameters rely on Facelets. Only Facelets can provide the necessary separation between template parsing and component tree construction that allows a template fragment to be processed in isolation. The result of this operation is a genuine UI component tree, represented by UIViewRoot, that contains only the view metadata facet and its children. For all intents and purposes, it's as though the view template only contained this one child element. Using the following logic, it's possible to retrieve the metadata for an arbitrary view at any point in time. This data mining will come in to play later when we talk about view parameter propagation. String viewId = "/your_view_id.xhtml" FacesContext ctx = FacesContext.getCurrentInstance(); ViewDeclarationLanguage vdl = ctx.getApplication().getViewHandler() .getViewDeclarationLanguage(ctx, viewId); ViewMetadata viewMetadata = vdl.getViewMetadata(ctx, viewId); UIViewRoot viewRoot = viewMetadata.createMetadataView(ctx); UIComponent metadataFacet = viewRoot.getFacet(UIViewRoot.METADATA_FACET_NAME); At this point you could retrieve the UIViewParameter components, which are children of the facet, to perhaps access the view parameter mappings. More likely, though, you'll be looking for your own custom components so you can execute custom behavior before the view is rendered (e.g., view actions). The extraction of the view metadata is very clever because, while it only builds a partial view, it still honors Facelets compositions. That means you can put your metadata into a common template and include it. Using some creative arrangement, you can apply common metadata to a pattern of views. Here's an example: ... ... You've learned that defining a view metadata facet provides the following services for JSF: Arbitrarily complex metadata, which can reuse existing component infrastructure Metadata is kept with the view, or in a shared template, instead of in an external XML file Can be extracted and processed without any side effects (idempotent) Common metadata declarations can be shared across multiple views Now that you are well versed in the view metadata facet, it's time to work out a concrete example of view parameters in practice. We'll look at how to enforce preconditions and load data on an initial request using information from the query string. Then you'll learn how that information gets propagated as the user navigates to other views. Weaving parameters into the life cycle This article has alluded several times to the use case of loading a blog entry from a URL by passing the value of the id parameter to our managed bean on an initial request. Let's allow this scenario to play out. Here's the URL the user might request coming into the site: http://domain/blog/entry.jsf?id=9 We'll start by asking what we do with the value once it is assigned to the entryId property of the blog managed bean. One approach is to load the entry lazily as soon as it's referenced in the UI. #{blog.blogEntry.title} #{blog.blogEntry.content} Here's what the managed bean would look like to support this approach: @ManagedBean(name = "blog") public class Blog { private Long entryId; private BlogEntry blogEntry; public Long getEntryId() { return entryId; } public void setEntryId(Long entryId) { this.entryId = entryId; } public BlogEntry getBlogEntry() { if (blogEntry == null) { blogEntry = blogRepository.findEntry(entryId); } return blogEntry; } } Of course, it doesn't make any sense to display an entry without an id (and could even lead to a NullPointerException). So we should really make the id request parameter required. We'll also add a message if it is missing. ... In the case a required request parameter is missing, you can display the error message using the tag. Conversion and validation failures are recorded as global messages since there's no view element with which to associate. But these preconditions still don't stop the view from being rendered if a request parameter is missing or invalid. What we need is a way to execute an initialization method that parallels an action invocation on a postback. That would allow us to get everything sorted before the user sees a response. View initialization While view parameters provide the processing steps from retrieving the request value to updating the model, they do not furnish the action invocation and navigation steps that are part of the faces request life cyle. That means you have to fall back to lazy loading the data as the view is being rendered (i.e., encoded). You are also missing a definitive point to fine tune the UI component tree programmatically before it's encoded. Fortunately, another new feature in JSF 2, system events, makes it possible to perform a series of initialization steps before view rendering begins. Systems events notify registered listeners of interesting transition points in the JSF life cycle at a much finer-grained level than phase listeners. In particular, we are interested in the PreRenderViewEvent, which is fired immediately after the component tree is built (but not yet rendered). If the word "registered" evokes dreadful memories of XML descriptors, fear not. Observing the event we are interested in is just a matter of appending one or more elements to the view metadata facet. The tag has two required attributes, type and listener. The type attribute is the name of the event to observe derived by removing the Event suffix from the end of the event class name and decaptializing the result. We are only interested in one event, preRenderView. The listener attribute is a method binding expression pointing to either a no-arguments method or a method that accepts a SystemEvent. ... We can use this method to retrieve the blog entry before the view is rendered. public void loadEntry() { blogEntry = blogRepository.findEntry(entryId); } If the entry cannot be found, you could add conditional logic to the view to display an error message: The blog entry you requested does not exist. Ideally, it would be better not to display the view at all. You can force a navigation to occur using the NavigationHandler API. public void loadEntry() { try { blogEntry = blogRepository.findEntry(entryId); } catch (NoSuchEntryException e) { FacesContext ctx = FacesContext.getCurrentInstance(); ctx.getApplication().getNavigationHandler() .handleNavigation(ctx, "#{blog.loadEntry}", "invalid"); } } The only problem is that the listener method is going to be invoked even if the view parameter could not be successfully converted, validated and assigned to the model property. Once again, there's a JSF 2 feature to the rescue. You can use the new isValidationFailed() method on FacesContext to check whether a conversion or validation failure occurred while processing the view parameters. public void loadEntry() { FacesContext ctx = FacesContext.getCurrentInstance(); if (ctx.isValidationFailed()) { ctx.getApplication().getNavigationHandler() .handleNavigation(ctx, "#{blog.loadEntry}", "invalid"); return; } // load entry } So far we have dealt with a trivial string to long conversion. But view parameters allow you to represent more complex data, as long as you have a converter that can marshal the value from (and to) a string. Let's assume that we want to allow the user to look at blog entries that fall within a range of dates. The before and after dates can be encoded into the URL as follows: /entries.jsf?after=2007-12-31&before=2009-01-01 Those values can then be converted to Date objects using the converter tag and assigned to Date properties on a managed bean as follows: We again use a PreRenderViewEvent listener to load the data before the page is rendered, in this case filtering the collection of blog entries to be displayed. Emulating the behavior of an action-oriented framework, which the previous examples have demonstrated, is one use of the PreRenderViewEvent. Another is to act as a life cycle callback for programmatically creating or tweaking the UI component tree after it is "inflated" from the view template. Perhaps you want to build part of the tree dynamically from a data structure. Accomplishing this in JSF would require "binding" a bean property to an existing UI component, declared using an EL value expression in the binding attribute of the tag. But this approach is really ugly because you have to put the tree-appending logic in either the JavaBean property getter or setter, depending on whether the view is being created or restored. The PreRenderViewEvent offers a much more definitive and self-documentating hook. As you've seen, it's finally possible to respond to a bookmarkable URL in JSF (without pain or brittle code). But, up to this point, all we've done is take, take, take. For bookmarkable support to be complete, we need to be able to create bookmarkable URLs. That brings us to the topic of parameter propagation. Push the parameters on If view parameters were only capable of accepting data sent through the query string of the URL, even considering the built-in conversion and validation they provide, they really wouldn't be all that helpful. What makes them so compelling is that they are bi-directional, meaning they are also propagated to subsequent requests, and rather transparently. The subsequent request may be a faces request, which targets the current view, or a non-faces request to a view that has view parameters, which translates into a bookmarkable URL. A request for a bookmarkable URL can come from either a link in the page or a redirect navigation event. We'll look at how view parameters get propagated in all of these cases in this section. Saved by the component tree Let's return to the blog entry view and consider what happens if we have a comment form below the post. The comment form might be defined as follows: Notice that there is no reference to the id of the blog entry in this form. Assuming that the blog entry is not stored in session scope (or a third-party conversation), how will the handler know which entry the comment should be linked? This is where view parameter propagation blends with component tree state saving. When encoding of the view (i.e., rendering) is complete, the view parameter values are tucked away in the saved state of the UI component tree. When the component tree is restored on a postback, such as when the comment form is submitted, the saved view parameter values are applied to the model. This allows view parameters to tie in nicely with the existing design of JSF. The initial state supplied to the view parameters by the URL can be maintained as long as the user interacts with the view (e.g., triggers faces requests through user interface events). You can think of view parameters as an elegant replacement for hidden form fields in this case. If the user bookmarked the URL after posting a comment, however, the reference to the blog entry would be lost. That's because after a POST request, the browser location does not contain a query string. Here's what the user would see: http://domain/blog/entry.jsf If we are following best practices, we'll want to implement the Post/Redirect/Get pattern anyway. That gives us a opportunity to repopulate the query string of the URL. In the past, this would have required an explicit call to the redirect() method of ExternalContext inside the action method. FacesContext.getCurrentInstance().getExternalContext().redirect("/entry.jsf?id=" + blog.getEntryId()); This explicit (and intrusive) call was necessary because the navigation case did not provide any way to append parameters to the query string. Now, view parameters can take care of this for us. We can tell JSF to encode the view parameters of the target view ID into the redirect URL by enabling the include-redirect-params attribute on the element. /entry.xhtml #{commentHandler.post} #{view.viewId} We'll get into navigation more in the next article in this series. Let's talk about those regular old hyperlinks in the page. We want those to be bookmarkable as well. That means the state needs to be encoded into the URL they point to. Once again, view parameters come into play. Bookmarkable links Let's now assume we want to create a bookmarkable link (permalink) to the current blog entry. You can link directly to another JSF view using the outcome attribute of the new hyperlink-producing component tags, and . These component tags are represented by the component class javax.faces.component.UIOutcomeTarget. (The reason the attribute is named outcome and not viewId will be explained in the next article. For now, just know that the value of the outcome attribute can be a view ID). Both of these component tags support encoding the view parameters into the query string of the URL as signaled by the includeViewParams attribute. Here's how the permalink is defined: The default value of includeViewParams is false. Since it's set to true, the view parameters are read in reverse and appended to the query string of the link. Here's the HTML that this component tag generated, assuming an entry id of 9: Permalink The link is produced using the new getBookmarkableURL() method on the ViewHandler API. This method calls through to the encodeBookmarkableURL() on the ExternalContext API to have the session ID token tacked on, if necessary. These methods complement the getRedirectURL() and encodeRedirectURL() methods on ViewHandler and ExternalContext, respectively. In a servlet environment, the implementations happen to be the same, but the extra methods serve as both a statement of intent and an extension point for environments where a link URL and a redirect URL are handled differently, such as a portlet. Notice that the context path of the application (/blog) is prepended to the path, the extension is changed from the view suffix (.xhtml) to the JSF servlet mapping (.jsf) and the query string contains the name and value of the view parameter read from the model. If you had used an tag, you would have had to do all of these things manually. That's exactly why the EG felt it was necessary to introduce this component. We can do one better. If the outcome attribute is absent, the current view ID is assumed. So we can shorten the tag to this: If you want the link to appear as a button, you can use the component tag instead. However, note that JavaScript is required in this case to update the browser location when the button is clicked, as you can see from the generated HTML: Permalink View parameters come in especially handy when the number of parameters to keep track of increases. For instance, let's consider the case when a user is searching for entries using a query string in a particular category and wants to paginate through the results. In this case, we are dealing with at least three parameters: Yet the link to these search results still remains as simple as the permalink to an entry: This component tag will produce HTML similar to this: Refresh What if we want to link back to the previous page? In that case, we cannot allow the view parameter named page be automatically written into the query string since that will just link us to the current page. We need an override. Fortunately, it's easy to override an encoded view parameter. You simply use the standard tag, just as you would if you were defining a new query string parameter: View parameters that are encoded into links to the current view ID are pretty intuitive. Where things get tricky is when we use view parameters on a link to a different view ID. This requires putting on your thinking cap and doing some reasoning. View parameter handoff When a request is made for a URL, and in turn a JSF view ID, the view parameters defined in that view are used to map request parameters to model properties. But when the view parameters are encoded into a bookmarkable URL, the mappings are read from the target view ID. That's why it's especially important to be able to extract the view metadata from a template without having building a full component tree, as mentioned earlier. Otherwise, you would end up building a component tree for every view that is linked to in the current view. That would be very costly. Let's consider a use case. Suppose that we want to create a link from the search results to a single entry. We would define the link as follows: #{_entry.title} #{_entry.excerpt} The question to ask yourself is this. "Are the search string, category and page offset included in the URL for the entry?". I hope you said "No". The reason is because when the URL for the entry link is built, the component tag reads the view parameter mappings defined in the /entry.xhtml template. The only parameter mapped in that template is entry id. In order to preserve the filter vector, the view parameters defined in the /entries.xhtml view need to also be in the /entry.xhtml template. Aha! Since these are shared view parameters, we should define them in a common template: We can then include that template in each view that needs to preserve these view parameters: ... Keep in mind that if the user navigates to the entry after performing a search, the URL for the entry shown in the browser's location bar will now contain the filter vector. But if you want the user to be able to return to the search filter (without using the back button), that's what you want. You can always provide a simple permalink to bookmark just the entry. Even though you are now defining view parameters in each of the views, that doesn't mean the URL will become littered with empty query string parameters when they are not in use. View parameters are only encoded (i.e., added to the query string) if the value is not null. Otherwise, there is no trace of the view parameter. You have now learned how view parameters are propagated during a postback, on a redirect and into a bookmarkable URL. The main benefit of this process is that it is transparent. You don't have to worry about each and every request parameter that comprises the state in the query string of the URL. Instead, JSF interprets the view parameter metadata defined in the template of the target view and automatically appends those name/value pairs to the URL when you activate this feature. Bookmark it View parameters serve as an alternative to storing state in the UI component tree, provide a starting point for the application, help integrate with legacy applications, assert preconditions of views, make views bookmarkable, and, with help of the new UIOutcomeTarget components or the enhancement to the redirect navigation case, produce links to those bookmarkable views. This article began by introducing you to the view metadata facet, which is a general facility for defining a view's metamodel that reuses the existing UI component infrastructure. You learned that view parameters and PreRenderViewEvent listeners are the first standard implementations of view metadata. You saw how the combination of these two features allow you to capture initial state from URL query string, validate preconditions and load data for a view all before the view is rendered. Finally, you learned how view parameter values are propagated to subsequent requests. This series continues by taking a deeper look at the navigation enhancements made in JSF 2 and explaining how those changes tie into the bookmarkability that you learned about in this article. So bookmark and check back again soon!
October 29, 2009
by Dan Allen
· 103,197 Views
article thumbnail
Fault Injection Testing - First Steps with JBoss Byteman
Fault injection testing[1] is a very useful element of a comprehensive test strategy in that it enables you to concentrate on an area that can be difficult to test; the manner in which the application under test is able to handle exceptions. It's always possible to perform exception testing in a black box mode, where you set up external conditions that will cause the application to fail, and then observe those application failures. Setting and automating (and reproducing) these such as these can, however, be time consuming. (And a pain in the neck, too!) JBoss Byteman I recently found a bytecode injection tool that makes it possible to automate fault injection tests. JBoss Byteman[2] is an open-source project that lets you write scripts in a Java-like syntax to insert events, exceptions, etc. into application code. Byteman version 1.1.0 is available for download from: http://www.jboss.org/byteman - the download includes a programmer's guide. There's also a user forum for asking questions here: http://www.jboss.org/index.html?module=bb&op=viewforum&f=310, and a jboss.org JIRA project for submitted issues and feature requests here: https://jira.jboss.org/jira/browse/BYTEMAN A Simple Example The remainder of this post describes a simple example, on the scale of the classic "hello world" example, of using Byteman to insert an exception into a running application. Let's start by defining the exception that we will inject into our application: package sample.byteman.test; /** * Simple exception class to demonstrate fault injection with byteman */ public class ApplicationException extends Exception { private static final long serialVersionUID = 1L; private int intError; private String theMessage = "hello exception - default string"; public ApplicationException(int intErrNo, String exString) { intError = intErrNo; theMessage = exString; } public String toString() { return "**********ApplicationException[" + intError + " " + theMessage + "]**********"; } } /* class */ There's nothing complicated here, but note the string that is passed to the exception constructor at line 13. Now, let's define our application class: package sample.byteman.test; /** * Simple class to demonstrate fault injection with byteman */ public class ExceptionTest { public void doSomething(int counter) throws ApplicationException { System.out.println("called doSomething(" + counter + ")"); if (counter > 10) { throw new ApplicationException(counter, "bye!"); } System.out.println("Exiting method normally..."); } /* doSomething() */ public static void main(String[] args) { ExceptionTest theTest = new ExceptionTest(); try { for (int i = 0; i < 12; i ++) { theTest.doSomething (i); } } catch (ApplicationException e) { System.out.println("caught ApplicationException: " + e); } } } /* class*/ The application instantiates an instance of ExceptionTest at line 18, then runs the doSomething method in a loop until a counter is greater then 10. Then it raises the exception that we defined earlier. When we run the application, we see this output: java -classpath bytemanTest.jar sample.byteman.test.ExceptionTest called doSomething(0) Exiting method normally... called doSomething(1) Exiting method normally... called doSomething(2) Exiting method normally... called doSomething(3) Exiting method normally... called doSomething(4) Exiting method normally... called doSomething(5) Exiting method normally... called doSomething(6) Exiting method normally... called doSomething(7) Exiting method normally... called doSomething(8) Exiting method normally... called doSomething(9) Exiting method normally... called doSomething(10) Exiting method normally... called doSomething(11) caught ApplicationException: **********ApplicationException[11 bye!]********** OK. Nothing too exciting so far. Let's make things more interesting by scripting a Byteman rule to inject an exception before the doSomething method has a chance to print any output. Our Byteman script looks like this: # # A simple script to demonstrate fault injection with byteman # RULE Simple byteman example - throw an exception CLASS sample.byteman.test.ExceptionTest METHOD doSomething(int) AT INVOKE PrintStream.println BIND buffer = 0 IF TRUE DO throw sample.byteman.test.ApplicationException(1,"ha! byteman was here!") ENDRULE Line 4 - RULE defines the start of the RULE. The following text on this line is not executed Line 5 - Reference to the class of the application to receive the injection Line 6 - And the method in that class. Note that since if we had written this line as "METHOD doSomething", the rule would have matched any signature of the soSomething method Line 7 - Our rule will fire when the PrintStream.println method is invoked Line 8 - BIND determince values for variables which can be referenced in the rule body - in our example, the recipient of the doSomething method call that triggered the rule, is identified by the parameter reference $0 Line 9 - A rule has to include an IF clause - in our example, it's always true Line 10 - When the rule is triggered, we throw an exception - note that we supply a string to the exception constructor Now, before we try to run this run, we should check the its syntax. To do this, we build our application into a .jar (bytemanTest.jar in our case) and use bytemancheck.sh sh bytemancheck.sh -cp bytemanTest.jar byteman.txt checking rules in sample_byteman.txt TestScript: parsed rule Simple byteman example - throw an exception RULE Simple byteman example - throw an exception CLASS sample.byteman.test.ExceptionTest METHOD doSomething(int) AT INVOKE PrintStream.println BIND buffer : int = 0 IF TRUE DO throw (1"ha! byteman was here!") TestScript: checking rule Simple byteman example - throw an exception TestScript: type checked rule Simple byteman example - throw an exception TestScript: no errors Once we get a clean result, we can run the application with Byteman. To do this, we run the application and specify an extra argument to the java command. Note that Byteman requires JDK 1.6 or newer. java -javaagent:/opt/Byteman_1_1_0/build/lib/byteman.jar=script:sample_byteman.txt -classpath bytemanTest.jar sample.byteman.test.ExceptionTest And the result is: caught ApplicationException: **********ApplicationException[1 ha! byteman was here!]********** Now that the Script Works, Let's Improve it! Let's take a closer look and how we BIND to a method parameter. If we change the script to read as follows: # # A simple script to demonstrate fault injection with byteman # RULE Simple byteman example - throw an exception CLASS sample.byteman.test.ExceptionTest METHOD doSomething(int) AT INVOKE PrintStream.println BIND counter = $1 IF TRUE DO throw sample.byteman.test.ApplicationException(counter,"ha! byteman was here!") ENDRULE In line 8, the BIND clause now refers to the int method parameter by index using the syntax $1. This change makes the value available inside the rule body by enabling us to use the name "counter." The value of counter is then supplied as the argument to the constructor for the ApplicationException class. This new version of the rule demonstrates shows how we can use local state as derived from the trigger method to construct our exception object. But wait there's more! Let's use the "counter" value as a counter. It's useful to be able to force an exception the first time a method is called. But, it's even more useful to be able to force an exception at a selected invocation of a method. Let's add a test for that counter value to the script: # # A simple script to demonstrate fault injection with byteman # RULE Simple byteman example 2 - throw an exception at 3rd call CLASS sample.byteman.test.ExceptionTest METHOD doSomething(int) AT INVOKE PrintStream.println BIND counter = $1 IF counter == 3 DO throw sample.byteman.test.ApplicationException(counter,"ha! byteman was here!") ENDRULE In line 9, we've changed the IF clause to make use of the counter value. When we run the test with this script, the first 2 calls to doSomething succeed, but the third one fails. One Last Thing - Changing the Script for a Running Process So far, so good. We've been able to inject a fault/exception into our running application, and even specify which iteration of a loop in which it happens. Suppose, however, we want to change a value in a byteman script, while the application is running? No problem! Here's how. First, we need to alter our application so that it can run for a long enough time for us to alter the byteman script. Here's a modified version of the doSomething method that waits for user input: public void doSomething(int counter) throws ApplicationException { BufferedReader lineOfText = new BufferedReader(new InputStreamReader(System.in)); try { System.out.println("Press "); String textLine = lineOfText.readLine(); } catch (IOException e) { e.printStackTrace(); } System.out.println("called doSomething(" + counter + ")"); if (counter > 10) { throw new ApplicationException(counter, "bye!"); } System.out.println("Exiting method normally..."); } If we run this version of the application, we'll see output like this: Press called doSomething(0) Exiting method normally... Press called doSomething(1) Exiting method normally... Press called doSomething(2) Exiting method normally... caught ApplicationException: **********ApplicationException[3 ha! byteman was here!]********** Let's run the application again, but this time, don't press . While the application is waiting for input, create a copy of the byteman script. In this copy, change the IF clause to have a loop counter set to a different value, say '5.' Then, open up a second command shell window and enter this command: Byteman_1_1_0/bin/submit.sh sample_byteman_changed.txt Then, return to the first command shell window and start pressing return, and you'll see this output: Press redefining rule Simple byteman example - throw an exception called doSomething(0) Exiting method normally... Press called doSomething(1) Exiting method normally... Press called doSomething(2) Exiting method normally... Press called doSomething(3) Exiting method normally... Press called doSomething(4) Exiting method normally... caught ApplicationException: **********ApplicationException[5 ha! byteman was here!]********** So, we were able to alter the value in the original byteman script, without stopping the application under test! Pitfalls Along the Way Some of the newbee mistakes that I made along the way were: Each RULE needs an IF clause - even if you want the rule to always fire The methods referenced in a RULE cannot be static - if they are static, then there is no $0 (aka this) to reference Yes, I had several errors and some typos the first few times I tried this. A syntax checker is always my best friend. ;-) Closing Thoughts With this simple example, we're able to inject injections into a running application in an easily automated/scripted manner. But, We've only scratched the surface with Byteman. In subsequent posts, I'm hoping to explore using Byteman to cause more widespread havoc in software testing. References [1] http://en.wikipedia.org/wiki/Fault_injection [2] http://www.jboss.org/byteman (Special thanks to Andrew Dinn for his help! ;-)
October 16, 2009
by Len DiMaggio
· 17,487 Views
article thumbnail
Creating a Custom JSF 1.2 Component - With Facets, Resource Handling, Events and Listeners
I occasionally create custom JavaServer Faces components. Just enough to sort of remember what the steps are, but not nearly frequently enough to quickly put a new component together. This article demonstrates the quick step approach to creating a new custom component in the old fashioned way (that means: it is not a Facelets template based or an ADF Faces 11g Declarative Component). Its primary purpose is to help me quickly retrace my steps. But perhaps it will benefit some of you as well. The Shuffler component I will develop supports facets. It will render its facet children - one after the other. Which one is rendered first can be indicated through an attribute facetOrder (values normal, reverse and random), which is EL enabled. A shuffler-method-expression can optionally be set to provide the Shuffler with a shuffle-order-processor: the method is invoked with the list of facets to shuffle and will return it in the order in which to render the children. The component can render with a shuffle icon that when pressed causes the children to be shuffled. The Shuffler component allows registration of Shuffle Event Listeners, custom listeners that are informed whenever the shuffle event occurs. An example of how the Shuffler can be used inside a JSF page: Some elements of custom JSF components that are explicitly discussed in this article: dynamic attributes of type ValueExpression (EL enabled) attributes of type MethodExpression (also EL enabled) facets (custom) events and listeners Bare essentials for custom JSF components A custom JSF component is represented by a Java Class - one that extends from UIComponentBase. An instance of this class is created whenever a new page is rendered that contains the component (and for each occurrence of the component in the page, a new instance of the class is created). The component class holds the attributes that are set by the page developer and that determine the behavior and appearance of the component. The component class has the internal logic of the component and it deals for example with events and listeners. This class may also render the markup (HTML) for the component - though it is a better practice to leave the actual rendering to a Renderer class. public class Shuffler extends UIComponentBase { ... } Most custom JSF component will also have an associated Renderer class, that extends from Renderer. Note that some components will not actually be rendered (such as Listeners, Iterators or Parameters) and therefore will not have a Renderer class. The Renderer is not only responsible for rendering the HTML, it will also inspect (decode) the incoming request from the browser to see whether the request parameter map contains values that are of interest to the component - that indicate for example that a value has been entered or set on the component(’s representation in the browser) or an action has been executed against it. Note that one JSF component may have multiple Renderers, for example for different channels and protocols (to render a representation of the component in plain XML, in WML, in JavaFX or XUL) or for different user agents (Firefox, Internet Explorer) or themes (professional user, internet surfer). public class ShufflerRenderer extends SuperRenderer { ... } JavaServer Faces pages can be created in various ways - including programmatically, using Facelets and using JSP pages. The latter option, through JSP, is still the most common one, though that is about to change with JSF 2.0 favoring Facelets. Page developers using JSPs will describe the JSF component tree that will need to be instantiated in memory for rendering a certain View using a plain JSP page. The tags in the JSP page are normal JSP tags - described by TLD (tag library descriptors) - corresponding to JSF components and therefore JSF component classes. Every JSF component that needs to be used in JSPs has to have a corresponding JSP tag-class, one that will typically extend from UIComponentELTag (or just from TagSupport when no JSF component is added to the component tree for a certain tag, for example when that tag represents a listener or parameter). The Tag Class specifies which JSF Component it represents. It also indicates which Renderer should be used to render the component. This means that one component can have multiple JSP tags associated with it, each providing a different way of rendering the component. Note: the renderer can also be specified dynamically - taking user preferences or characteristics into account public class ShufflerTag extends UIComponentELTag { public static final String COMPONENT_TYPE = "nl.amis.jsf.UIShuffler"; public static final String RENDERER_TYPE = "nl.amis.jsf.ShufflerRenderer"; public String getComponentType() { return COMPONENT_TYPE; } public String getRendererType() { return RENDERER_TYPE; } ... } Tags representing JSF components need to be described in TLD files (Tag Library Descriptors) just like any other JSP tag.The entry in the TLD defines the tag label to use in the page, whether the tag can contain child-tags, some descriptive meta data and every attribute that can be configured in the tag. For each attribute the TLD-entry specifies the type, whether it is required and if the attribute can contain an EL expression passing in a value or an EL expression passing in a method; in the latter case, the entry also prescribes the signature of the method: ShufflerLib 1.0 ShufflerLib /nl.amis,jsf/ShufflerLib Writes a DIV element that contains the facets in a specific order. shuffler nl.amis.jsf.shuffler.ShufflerTag JSP id false true rendered false boolean binding false javax.faces.component.UIComponent styleClass false java.lang.String .... JSF components need to be registered in a special faces-config.xml file (special in the sense that it is not the faces-config.xml that drives a web application but rather one that acts like a repository of components and their renderers. Note however that all entries in this special faces-config.xml is merged together with the ‘normal’ faces-config.xml. That means in turn that while the special file is primarily seen as the registry of components, it can also configure PhaseListeners, Navigation Rules (hard to see the value in that) and Managed Beans (which can be very useful). The component registration in faces-config.xml consists of a component type that is associated with a the component class. nl.amis.jsf.UIShuffler nl.amis.jsf.shuffler.Shuffler Renderers can also be registered in this file. A renderer entry registers a renderer-type (corresponding to the value returned by the getRendererType() method in the tag class) associated with the RendererClass. Based on the value (rendererType) returned by the tag class, the correct class to instantiate can be determined from this entry: nl.amis.Shuffler nl.amis.jsf.ShufflerRenderer nl.amis.jsf.shuffler.ShufflerRenderer Implementing the Classes: Component, Renderer and TagHandler The TagHandler ShufflerTag is the intermediary between the world of JSP pages (and the Servlet/JSP engine that translates the JSP file into a servlet class) and the JSF realm. Every tag in the JSP page needs to be turned into its corresponding JSF representation. The tag handler needs to override the setProperties() method inherited from the UIComponentELTag class; this method takes all the values set on the tag attributes in the page and passes them onwards to the Component. In our initial case, the tag is used in JSPs like this: ... other content The styleClass attribute is the only one we defined - id and rendered are defined on every JSP-tag based on JSF’s UIComponentELTag. Thye styleClass attribute is also the only attribute we need to take responsibility for in the tag class, by providing a setter method that sets a private member and by passing the value of that private member to the component in the setProperties() method. The code for the ShufflerTag class now becomes: package nl.amis.jsf.shuffler; import javax.el.ValueExpression; import javax.faces.component.UIComponent; import javax.faces.webapp.UIComponentELTag; public class ShufflerTag extends UIComponentELTag { public static final String COMPONENT_TYPE = "nl.amis.jsf.UIShuffler"; public static final String RENDERER_TYPE = "nl.amis.jsf.ShufflerRenderer"; private ValueExpression styleClass; public String getComponentType() { return COMPONENT_TYPE; } public String getRendererType() { return RENDERER_TYPE; } protected void setProperties(UIComponent component) { super.setProperties(component); processProperty(component, styleClass, Shuffler.STYLECLASS_ATTRIBUTE_KEY); } public void release() { super.release(); styleClass= null; } protected final void processProperty(final UIComponent component, final ValueExpression property, final String propertyName) { if (property != null) { if(property.isLiteralText()) { component.getAttributes().put(propertyName, property.getExpressionString()); } else { component.setValueExpression(propertyName, property); } } } public void setStyleClass(ValueExpression styleClass) { this.styleClass = styleClass; } } We cater for the fact that styleClass can contain a ValueExpression - as all attributes can, starting from JSF 1.2. In the method processProperty we check whether the string passed for styleClass is a literal string or should be considered an EL expression. In the latter case, we pass a ValueExpression to the component, otherwise a ‘normal’ attribute. Also note that the super class takes care of the attributes id, rendered and binding. However, we do have to specify them in the tag-library. The component class in our case leads a pretty comfortable life: the tag handler informs him of all the attribute values and the actual rendering is left to a special Renderer class. The component is a pretty passive element in this simple example: package nl.amis.jsf.shuffler; import javax.faces.component.UIComponentBase; import javax.faces.context.FacesContext; public class Shuffler extends UIComponentBase { public static final String FAMILY = "nl.amis.Shuffler"; public static final String STYLECLASS_ATTRIBUTE_KEY = "styleClass"; public String getFamily() { return FAMILY; } @Override public Object saveState(FacesContext facesContext) { Object values[] = new Object[2]; values[0] = super.saveState(facesContext); values[1] = this.getAttributes().get(STYLECLASS_ATTRIBUTE_KEY); return values; } @Override public void restoreState(FacesContext facesContext, Object state) { Object values[] = (Object[])state; super.restoreState(facesContext, values[0]); this.getAttributes().put(STYLECLASS_ATTRIBUTE_KEY, values[1]); } } The only really useful thing the component does is implementing the saveState and restoreState methods. These methods play an important part in turning the state of the component into a serializable object array and restoring that state of the component in the RestoreView phase, based on the serialized array. The Tag Handler specifies in its getRendererType() method that the renderer to use for this component when using the shuffler tag, is one called nl.amis.jsf.ShufflerRenderer. In the faces-config.xml file, we have indicated that this renderer type is associated with the class nl.amis.jsf.shuffler.ShufflerRenderer that extends Renderer. The renderers in JSF can override methods like encodeBegin(), encodeEnd(), encodeChildren() and decode() - the latter only when we have to process the incoming request, looking for new values set on or events that occurred on the component. In our case, we initially will simply have the ShufflerRenderer render a DIV element with a class attribute (based on the styleClass attribute). The DIV will allow the children of the Shuffler component to render - by not overriding the encodeChildren() method. package nl.amis.jsf.shuffler; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.render.Renderer; public class ShufflerRenderer extends Renderer { @Override public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException { super.encodeBegin(facesContext, component); final ResponseWriter writer = facesContext.getResponseWriter(); writer.startElement("DIV", component); String styleClass = (String)attributes.get(Shuffler.STYLECLASS_ATTRIBUTE_KEY); writer.writeAttribute("class", styleClass, null); } @Override public void encodeEnd(final FacesContext facesContext, final UIComponent component) throws IOException { final ResponseWriter writer = facesContext.getResponseWriter(); writer.endElement("DIV"); } } Next steps - working with facets The Shuffler component is created to dynamically (re)order its child contents. It will do so using facets. The content you want this component to shuffle is passed in two or more facets. The facets are named using string representations of integers, so for example: ... content ... content ... content Facets are automatically supported on JSF components. The getFacets() method is available inside the Shuffler component class and will return a collection of facet UIComponents. Facets are special children for a JSF component: the framework will never render the contents of facets on its own. It is up to the component to determine when and how to render the contents of its facets. So, there is some work to do for the ShuffleRenderer class. But first we need to add support for the new facetOrder attribute. Adding an attribute means: adding an attribute entry in the TLD adding support for processing the attribute in the Tag Handler (a setter and a line of code in setProperties()) adding the attribute in saveState() and restoreState() in the Component class Here we go: In the tld entry, add: facetOrder false java.lang.String In the tag-handler class ShufflerTag add: private ValueExpression facetOrder; public void setFacetOrder(ValueExpression facetOrder) { this.facetOrder = facetOrder; } and in setProperties(): processProperty(component, facetOrder, Shuffler.FACETORDER_ATTRIBUTE_KEY); Finally in the component class Shuffler , add: public static final String FACETORDER_ATTRIBUTE_KEY = "facetOrder"; @Override public Object saveState(FacesContext facesContext) { Object values[] = new Object[3]; values[0] = super.saveState(facesContext); values[1] = this.getAttributes().get(STYLECLASS_ATTRIBUTE_KEY); values[2] = this.getAttributes().get(FACETORDER_ATTRIBUTE_KEY); return values; } @Override public void restoreState(FacesContext facesContext, Object state) { Object values[] = (Object[])state; super.restoreState(facesContext, values[0]); this.getAttributes().put(STYLECLASS_ATTRIBUTE_KEY, values[1]); this.getAttributes().put(FACETORDER_ATTRIBUTE_KEY, values[2]); } The Shuffler also needs to make the facets available to the renderer, in the order that is prescribed by the facetOrder attribute. This attribute supports three values: normal, reverse and random. public List getOrderedFacets(FacesContext facesContext) { // allowable values: normal (default) and reverse // the normal order of the facets is determined by ordering the facets by name (assuming the facetnames are string representations of integers) // create a sorted list with the integers representing the facets List facetIndexValues = new ArrayList(); List facetNames = new ArrayList(getFacets().keySet()); for (String facetName : facetNames) { facetIndexValues.add(new Integer(facetName)); } Collections.sort(facetIndexValues); // create the list of facets corrresponding to the sorted list of facet index values List orderedFacets = new ArrayList(); for (Integer index : facetIndexValues) { orderedFacets.add(getFacets().get(index.toString())); } // depending on the value for the facetOrder attribute, we may need to reorganize the orderedFacets list String facetOrder = (String)this.getAttributes().get(Shuffler.FACETORDER_ATTRIBUTE_KEY); if ("reverse".equalsIgnoreCase(facetOrder)) { Collections.reverse(orderedFacets); } else if ("random".equalsIgnoreCase(facetOrder)) { Collections.shuffle(orderedFacets); } else if ("normal".equalsIgnoreCase(facetOrder)) { // need to do nothing as with normal the order returned by getFacets() is the correct one } return orderedFacets; } The ShufflerRenderer will have to do the real work. It will retrieve the facets - in the proper order - from the Shuffler Component class and ask JSF to render them. package nl.amis.jsf.shuffler; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.render.Renderer; import javax.faces.component.UIComponent; public class ShufflerRenderer extends Renderer { @Override public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException { super.encodeBegin(facesContext, component); final ResponseWriter writer = facesContext.getResponseWriter(); writer.startElement("DIV", component); String styleClass = (String)attributes.get(Shuffler.STYLECLASS_ATTRIBUTE_KEY); writer.writeAttribute("class", styleClass, null); List orderedFacets = ((Shuffler)component).getOrderedFacets(facesContext); for (UIComponent facet:orderedFacets) { facet.encodeAll(facesContext); } } @Override public void encodeEnd(final FacesContext facesContext, final UIComponent component) throws IOException { final ResponseWriter writer = facesContext.getResponseWriter(); writer.endElement("DIV"); } } With these changes, we can now add real content to the Shuffler and have it rendered, in the order we specified - which can be random. Also note that we can use an EL expression to have the facetOrder dynamically derived: facetOrder="#{bean.liveFacetOrder}" id="s1" > ... content ... content ... content Downloading Resources The next step in our exploration of the development of custom JSF components is the addition of resources like images and JavaScript libraries. Note that in JavaServer Faces 2.0 a new facility is available, especially for this purpose. However, in our 1.2 setting we have to come up with something ourselves. That is not to say no solutions exist for JSF 1.2; almost every library comes with a form of resource handling. Then there is the Weblet framework that was introduced especially for this purpose. Another option leverages JSF itself: its capability through PhaseListeners to intercept a request, interpret the requested ViewId and optionally serve up an image or JS file in response to the request. This approach is proposed in JavaServer Faces, The Complete Reference by Ed Burns and Chris Schalk. I have slightly modified there code for my own purposes. However, the central idea clearly is theirs. My objective is to add an image to the Shuffler component. The next step will be to allow the user to click on the image and by doing so tgrigger a re-shuffle. But that part is for later, first add the image itself. The HTML rendered by the ShufflerRenderer needs to be extended with the IMG tag, that is easy enough. Less trivial is the value for the SRC attribute on the IMG tag. The change in the encodeBegin method in the ShufflerRenderer: writer.startElement("IMG", component); writer.writeAttribute("src", imageUrl( facesContext,SHUFFLE_IMAGE), null); writer.writeAttribute("alt", "Click to reshuffle", null); writer.writeAttribute("width", "20px", null); writer.endElement("IMG"); With SHUFFLE_IMAGE specified as: private static String SHUFFLE_IMAGE = "shuffleIcon.png"; The imageUrl() method is defined as follows private final static String IMAGE_PATH ="/faces/images/"; protected String imageUrl(FacesContext facesContext, String image) { ViewHandler handler = facesContext.getApplication().getViewHandler(); String imageUrl = handler.getResourceURL(facesContext, IMAGE_PATH + image); return imageUrl; } The URLs for images are now constructed to look like this: http://somehost:7101/CustomJSFConsumer/faces/images/shuffleIcon.png The request for the shuffleIcon.png that is sent by the browser should be intercepted by a component that knows how to handle it. Because of the /faces/ part, this request is sent to the FacesServlet and processed through the JSF lifecycle. The componoent to intercept it will be a phaseListener that fires after restore view. It inspects the ViewId. When the ViewId contains the predefined indicator ("/images/") it steps in and takes over processing of the request. It will find the name of the image that is requested by taking the part of the ViewId that comes after /images/. It will then locate the image file on the classpath (that works well for a component packaged in a jar file, it can have the images packaged in the jar file too), looking for a directory called /images/ - as specified by the IMAGE_PATH constant. It copies the image from the file to the outputstream after setting the content type. package nl.amis.jsf; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.URL; import java.net.URLConnection; import javax.faces.context.FacesContext; import javax.faces.event.PhaseEvent; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletResponse; public class ResourceServerPhaseListener implements PhaseListener { public ResourceServerPhaseListener() { super(); } public PhaseId getPhaseId() { return PhaseId.RESTORE_VIEW; } public void afterPhase(PhaseEvent event) { // If this is restoreView phase if (PhaseId.RESTORE_VIEW == event.getPhaseId()) { if (-1 != event.getFacesContext().getViewRoot().getViewId().indexOf(RENDER_IMAGE_TAG)) { // extract the name of the image resource from the ViewId String image = event.getFacesContext().getViewRoot().getViewId().substring(event.getFacesContext() .getViewRoot().getViewId().indexOf(RENDER_IMAGE_TAG) + RENDER_IMAGE_TAG.length()); // render the script writeImage(event, image); event.getFacesContext().responseComplete(); } } } public void beforePhase(PhaseEvent event) { } public static final String RENDER_IMAGE_TAG = "/images/"; public static final String IMAGE_PATH = "/images/"; private void writeImage(PhaseEvent event, String resourceName) { URL url = getClass().getResource(IMAGE_PATH + resourceName); URLConnection conn = null; InputStream stream = null; HttpServletResponse response = (HttpServletResponse)event.getFacesContext().getExternalContext().getResponse(); try { conn = url.openConnection(); conn.setUseCaches(false); stream = conn.getInputStream(); ServletContext servletContext = (ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext(); String mimeType = servletContext.getMimeType(resourceName); response.setContentType(mimeType); response.setStatus(200); // Copy the contents of the file to the output stream byte[] buf = new byte[1024]; int count = 0; while ((count = stream.read(buf)) >= 0) { response.getOutputStream().write(buf, 0, count); } response.getOutputStream().close(); } catch (Exception e) { String message = null; message = "Can't load image file:" + url.toExternalForm(); try { response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); } catch (IOException f) { f.printStackTrace(); } } } } PhaseListeners need to be configured in order to be active. This configuration usually is done in the faces-config.xml of the application. Fortunately, we can also configure the PhaseListener in the faces-config.xml file that we create for the custom component. This faces-config.xml is part of the jar file in which the custom component is shipped and deployed. Its contents are merged with the application’s own faces-config.xml. The registration of our PhaseListener looks like this: nl.amis.jsf.ResourceServerPhaseListener ... Triggering events on the custom component Time to take another big step. We will support clicking the image by the end user and turn that event into a reshuffle of the facets of the Shuffler component. In the next section we will not only act on that click ourselves, but also publish an event that others can listen to. We will have to add a JavaScript event listener in the HTML rendered for the Shuffler. This client side code is triggered when the image is clicked. It will submit the form - after it has added an input element to the DOM and set a value on it. Note: this approach to have a custom component trigger an event that can be received by the server side renderer class has been described in Pro JSF and Ajax: Building Rich Internet Components - by John R. Fallows and Jonas Jacobi, the guys who first introduced me to JavaServer Faces. The JavaScript for the Shuffler component looks like this: /** * The onclick handler for ShufflerRenderer. * * @param formClientId the clientId of the enclosing UIForm component * @param clientId the clientId of the Shuffler component */ function _shuffle_click( formClientId, clientId) { var form = document.forms[formClientId]; var input = form[clientId]; if (!input) // if the input element does not already exist, create it and add it to the form { input = document.createElement("input"); input.type = 'hidden'; input.name = clientId; form.appendChild(input); } input.value = 'clicked'; form.submit(); } The JavaScript is not be directly included in the page - as it is part of the jar file in which the Shuffler component is shipped. We need a way to attach this JavaScript (it is in a file called shuffle.js) to the page from within the custom component, or in this case rather its Renderer class. We extend the ResourceServerPhaseListener to also handle JavaScript resources, just like it can handle images. public class ResourceServerPhaseListener implements PhaseListener { public static final String RENDER_SCRIPT_TAG = "/js/"; public static final String RENDER_IMAGE_TAG = "/images/"; public static final String SCRIPT_PATH = "/js/"; public static final String IMAGE_PATH = "/images/"; public PhaseId getPhaseId() { return PhaseId.RESTORE_VIEW; } public void afterPhase(PhaseEvent event) { // If this is restoreView phase if (PhaseId.RESTORE_VIEW == event.getPhaseId()) { // if the request is for a JavaScript library if (-1 != event.getFacesContext().getViewRoot().getViewId().indexOf(RENDER_SCRIPT_TAG)) { // extract the name of the script from the ViewId String script = event.getFacesContext().getViewRoot().getViewId().substring(event.getFacesContext() .getViewRoot().getViewId().indexOf(RENDER_SCRIPT_TAG) + RENDER_SCRIPT_TAG.length()); // render the script writeScript(event, script); event.getFacesContext().responseComplete(); } ... image handling, same as before } } public void beforePhase(PhaseEvent event) { } private void writeScript(PhaseEvent event, String resourceName) { URL url = getClass().getResource(SCRIPT_PATH + resourceName); URLConnection conn = null; InputStream stream = null; BufferedReader bufReader = null; HttpServletResponse response = (HttpServletResponse)event.getFacesContext().getExternalContext().getResponse(); OutputStreamWriter outWriter = null; String curLine = null; try { outWriter = new OutputStreamWriter(response.getOutputStream(), response.getCharacterEncoding()); conn = url.openConnection(); conn.setUseCaches(false); stream = conn.getInputStream(); bufReader = new BufferedReader(new InputStreamReader(stream)); response.setContentType("text/javascript"); response.setStatus(200); while (null != (curLine = bufReader.readLine())) { outWriter.write(curLine + "\n"); } outWriter.close(); } catch (Exception e) { String message = null; message = "Can't load script file:" + url.toExternalForm(); try { response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); } catch (IOException f) { f.printStackTrace(); } } } private void writeImage(PhaseEvent event, String resourceName) { ... same as before } } The Renderer class is responsible for rendering the markup that will include the JavaScript resources to the page (the script element). We could have multiple occurrences of our custom component in a page. However, the JavaScript file shuffle.js should be loaded only once, to prevent excessive and completely pointless browser requests. In order to make that happen, the Renderer indicates to a method writeScriptResource that it has a JavaScript resource that should be included. This method verifies whether a script tag for downloading that same resource has already been added in the current request. If so, it will not add another script tag. If not [already included] then the tag is added with its src attribute referring to the proper PhaseListener controlled url: protected void writeScriptResource( FacesContext context, String resourcePath) throws IOException { Set scriptResources = _getScriptResourcesAlreadyWritten(context); // Set.add() returns true only if item was added to the set // and returns false if item was already present in the set if (scriptResources.add(resourcePath)) { ViewHandler handler = context.getApplication().getViewHandler(); String resourceURL = handler.getResourceURL(context, SCRIPT_PATH +resourcePath); ResponseWriter out = context.getResponseWriter(); out.startElement("script", null); out.writeAttribute("type", "text/javascript", null); out.writeAttribute("src", resourceURL, null); out.endElement("script"); } } private Set _getScriptResourcesAlreadyWritten( FacesContext context) { ExternalContext external = context.getExternalContext(); Map requestScope = external.getRequestMap(); Set written = (Set)requestScope.get(_SCRIPT_RESOURCES_KEY); if (written == null) { written = new HashSet(); requestScope.put(_SCRIPT_RESOURCES_KEY, written); } return written; } static private final String _SCRIPT_RESOURCES_KEY = ShufflerRenderer.class.getName() + ".SCRIPTS_WRITTEN"; With these helper methods in place, the ShufflerRenderer can be extended to include the client side click handling code: @Override public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException { super.encodeBegin(facesContext, component); final Map attributes = component.getAttributes(); final ResponseWriter writer = facesContext.getResponseWriter(); String formClientId = _findFormClientId(facesContext, component); String shuffleClientId = component.getClientId(facesContext); writeScriptResource(context, "shuffle.js"); writer.startElement("DIV", component); String styleClass = (String)attributes.get(Shuffler.STYLECLASS_ATTRIBUTE_KEY); writer.writeAttribute("class", styleClass, null); writer.startElement("SPAN", component); writer.writeAttribute("onClick", "_shuffle_click('" + formClientId + "'," + "'" + shuffleClientId + "')", null); writer.startElement("IMG", component); writer.writeAttribute("src", imageUrl( facesContext,SHUFFLE_IMAGE), null); writer.writeAttribute("alt", "Click to reshuffle", null); writer.writeAttribute("width", "20px", null); writer.endElement("IMG"); writer.endElement("SPAN"); List orderedFacets = ((Shuffler)component).getOrderedFacets(facesContext); for (UIComponent facet:orderedFacets) { facet.encodeAll(facesContext); } } protected void encodeResources(FacesContext context, UIComponent component) throws IOException { writeScriptResource(context, "shuffle.js"); } /** * Finds the parent UIForm component client identifier. * * @param context the Faces context * @param component the Faces component * * @return the parent UIForm or RichForm (for usage in ADF) client identifier, if present, otherwise null */ private String _findFormClientId(FacesContext context, UIComponent component) { if (component==null) { return null; } if (component instanceof UIForm || component.getClass().getName().endsWith("RichForm")) { return component.getClientId(context); } else { return _findFormClientId(context, component.getParent()); } } The image is wrapped in a SPAN and the onclick event handler is defined on that SPAN element (this allows us to later on add more clickable stuff to the SPAN). When the image is clicked, the _shuffle_click function is invoked - that was loaded from shuffle.js. The element is added to the form and the form is submitted. The HTML rendered from this renderer now looks like this:
October 7, 2009
by Wouter Van Reeven
· 45,498 Views
article thumbnail
Multithreading and the Java Memory Model
At the New England Software Symposium, I attended Brian Goetz's session called "The Java Memory Model". When I saw the phrase "memory model" in the title I thought it would be about garbage collection, memory allocation and memory types. Instead, it is really about multithreading. The difference is that this presentation focuses on visibility, not locking or atomicity. This is my attempt to summarize his talk. The importance of visibility Visibility here refers to the memory that an executing thread can see once it is written. The big gotcha is that when thread A writes something before thread B reads it, it does not mean thread B will read the correct value. You could ensure that threads A and B are ordered with locking but you can still be in deep doo doo because the memory is not written and read in order, or is read in a partially written state. A big part of this peril comes from the layered memory architecture of modern hardware: multi-CPU, multi-core CPUs, multi-level caches on and off chip etc. Instructions could be executed in parallel or out of order. The memory being written may not even be in RAM at all: it could be on a remote core's register. But the danger could also come from old-fashioned compiler optimizations. One of Brian's examples is the following loop which depends on another thread to set the boolean field asleep: while (!asleep) ++sheep; The compiler may notice that asleep is loop-invariant and optimize its evaluation out of the loop if (!asleep) while (true) ++sleep; The result is an infinite loop. The fix in this case is to use a volatile variable. The Java Memory Model A memory model describes when one thread's actions are guaranteed to be visible to another. The Java memory model (JMM) is quite an achievement: previously, memory models were specific to each processor architecture. A cross-platform memory model takes portability well beyond being able to compile the same source code: you really can run it anywhere. It took until Java 5 (JSR 133) to get the JMM right. The JMM defines a partial ordering on program actions (read/write, lock/unlock, start/join threads) called happens-before. Basically, if action X happens-before Y, then X's results are visible to Y. Within a thread, the order is basically the program order. It's straightforward. But between threads, if you don't use synchronized or volatile, there are no visibility guarantees. As far as visible results go, there is no guarantee that thread A will see them in the order that thread B executes them. Brian even invoked special relativity to describe the disorienting effects of relative views of reality. You need synchronization to get inter-thread visibility guarantees. The basic tools of thread synchronization are: The synchronized keyword: an unlock happens-before every subsequent lock on the same monitor. The volatile keyword: a write to a volatile variable happens-before subsequent reads of that variable. Static initialization: done by the class loader, so the JVM guarantees thread safety In addition to the above, the JMM offers a guarantee of initialization safety for immutable objects. The Rules Here are points that Brian emphasized: If you read or write a field that is read/written by another thread, you must synchronize. This must be done by both the reading and writing threads, and on the same lock. Don't try to reason about ordering in undersynchronized programs. Avoiding synchronization can cause subtle bugs that only blow up in production. Do it right first, then make it fast. Case study: double-checked locking One example of synchronization avoidance gone bad is the popular double-checked locking idiom for lazy initialization, which we now know is broken: private Thing instance = null; public Thing getInstance() { if (instance == null) { synchronized (this) { if (instance == null) instance = new Thing(); } } return instance; } This idiom can result in a partially constructed Thing object, because it only worries about atomicity at the expense of visibility. There are ways to fix this, of course, such as using a volatile field or switching to using static initializers. But it's easy to get it wrong, so Brian questions why we would want to do something like this in the first place. The main motivation was to avoid synchronization in the common case. While it used to be expensive in the past, uncontended synchronization is much cheaper now. There is still a lot of advice to avoid supposedly expensive Java operations out there, but the JVM has improved tremendously and a lot of old performance tips (like object pooling) just don't make sense anymore. Beware of reading years-old advice when you Google for Java tips. Remember Brian's advice above against premature optimization. That said, he also showed a couple of better alternatives for lazy initialization. Some thoughts This talk was a reminder to me that low-level multithreading is hard. It's hard enough that it took years to get the JMM right. It's hard enough that a university professor would say "don't do it". And if you faithfully follow Brian's rules and use synchronization primitives everywhere, you might find yourself vulnerable to thread deadlocks (hmmm ... why does JConsole have a deadlock detection function?). The primary danger in multithreading is in shared, mutable state. Without shared mutable data, threads might as well be separate processes, and the danger evaporates. So while it's wonderful what JMM has done for cross-platform visibility guarantees, I think we would do ourselves a favor if we tried to minimize shared mutable data. There are often higher level alternatives. For example, Scala's Actor construct relies on passing immutable messages instead of sharing memory. From http://chriswongdevblog.blogspot.com/
October 5, 2009
by Christopher Wong
· 47,129 Views
article thumbnail
A Look Inside JBoss Microcontainer, Part 3 - the Virtual File System
We're finally back with our next article in the Microcontainer series. In the first two articles we demonstrated how Microcontainer supports , and showed its powerful . In this article, we'll explain Classloading and Deployers, but first we must familiarize ourselves with VFS. VFS stands, as expected, for Virtual File System. What does VFS solve for us, or why is it useful? Here, at JBoss, we saw that a lot of similar resource handling code was scattered/duplicated all over the place. In most cases it was code that was trying to determine what type of resource a particular resource was, e.g. is it a file, a directory, or a jar loading resources through URLs. Processing of nested archives was also reimplemented again, and again in different libraries. Read the other parts in DZone's exclusive JBoss Microcontainer Series: Part 4 -- ClassLoading Layer Example: public static URL[] search(ClassLoader cl, String prefix, String suffix) throws IOException { Enumeration[] e = new Enumeration[]{ cl.getResources(prefix), cl.getResources(prefix + "MANIFEST.MF") }; Set all = new LinkedHashSet(); URL url; URLConnection conn; JarFile jarFile; for (int i = 0, s = e.length; i < s; ++i) { while (e[i].hasMoreElements()) { url = (URL)e[i].nextElement(); conn = url.openConnection(); conn.setUseCaches(false); conn.setDefaultUseCaches(false); if (conn instanceof JarURLConnection) { jarFile = ((JarURLConnection)conn).getJarFile(); } else { jarFile = getAlternativeJarFile(url); } if (jarFile != null) { searchJar(cl, all, jarFile, prefix, suffix); } else { boolean searchDone = searchDir(all, new File(URLDecoder.decode(url.getFile(), "UTF-8")), suffix); if (searchDone == false) { searchFromURL(all, prefix, suffix, url); } } } } return (URL[])all.toArray(new URL[all.size()]); } private static boolean searchDir(Set result, File file, String suffix) throws IOException { if (file.exists() && file.isDirectory()) { File[] fc = file.listFiles(); String path; for (int i = 0; i < fc.length; i++) { path = fc[i].getAbsolutePath(); if (fc[i].isDirectory()) { searchDir(result, fc[i], suffix); } else if (path.endsWith(suffix)) { result.add(fc[i].toURL()); } } return true; } return false; } There were also many problems with file locking on Windows systems, which forced us to copy all hot-deployable archives to another location to prevent locking those in deploy folders (which would prevent their deletion and filesystem based undeploy). File locking was a major problem that could only be addressed by centralizing all the resource loading code in one place. Recognizing a need to deal with all of these issues in one place, wrapping it all into a simple and useful API, we created the VFS project. VFS public API Basic usage in VFS can be split in two pieces: simple resource navigation visitor pattern API As mentioned, in plain JDK resource handling navigation over resources is far from trivial. You must always check what kind of resource you're currently handling, and this is very cumbersome. With VFS we wanted to limit this to a single resource type - VirtualFile. public class VirtualFile implements Serializable { /** * Get certificates. * * @return the certificates associated with this virtual file */ Certificate[] getCertificates() /** * Get the simple VF name (X.java) * * @return the simple file name * @throws IllegalStateException if the file is closed */ String getName() /** * Get the VFS relative path name (org/jboss/X.java) * * @return the VFS relative path name * @throws IllegalStateException if the file is closed */ String getPathName() /** * Get the VF URL (file://root/org/jboss/X.java) * * @return the full URL to the VF in the VFS. * @throws MalformedURLException if a url cannot be parsed * @throws URISyntaxException if a uri cannot be parsed * @throws IllegalStateException if the file is closed */ URL toURL() throws MalformedURLException, URISyntaxException /** * Get the VF URI (file://root/org/jboss/X.java) * * @return the full URI to the VF in the VFS. * @throws URISyntaxException if a uri cannot be parsed * @throws IllegalStateException if the file is closed * @throws MalformedURLException for a bad url */ URI toURI() throws MalformedURLException, URISyntaxException /** * When the file was last modified * * @return the last modified time * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ long getLastModified() throws IOException /** * Returns true if the file has been modified since this method was last called * Last modified time is initialized at handler instantiation. * * @return true if modifed, false otherwise * @throws IOException for any error */ boolean hasBeenModified() throws IOException /** * Get the size * * @return the size * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ long getSize() throws IOException /** * Tests whether the underlying implementation file still exists. * @return true if the file exists, false otherwise. * @throws IOException - thrown on failure to detect existence. */ boolean exists() throws IOException /** * Whether it is a simple leaf of the VFS, * i.e. whether it can contain other files * * @return true if a simple file. * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ boolean isLeaf() throws IOException /** * Is the file archive. * * @return true if archive, false otherwise * @throws IOException for any error */ boolean isArchive() throws IOException /** * Whether it is hidden * * @return true when hidden * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ boolean isHidden() throws IOException /** * Access the file contents. * * @return an InputStream for the file contents. * @throws IOException for any error accessing the file system * @throws IllegalStateException if the file is closed */ InputStream openStream() throws IOException /** * Do file cleanup. * * e.g. delete temp files */ void cleanup() /** * Close the file resources (stream, etc.) */ void close() /** * Delete this virtual file * * @return true if file was deleted * @throws IOException if an error occurs */ boolean delete() throws IOException /** * Delete this virtual file * * @param gracePeriod max time to wait for any locks (in milliseconds) * @return true if file was deleted * @throws IOException if an error occurs */ boolean delete(int gracePeriod) throws IOException /** * Get the VFS instance for this virtual file * * @return the VFS * @throws IllegalStateException if the file is closed */ VFS getVFS() /** * Get the parent * * @return the parent or null if there is no parent * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ VirtualFile getParent() throws IOException /** * Get a child * * @param path the path * @return the child or null if not found * @throws IOException for any problem accessing the VFS * @throws IllegalArgumentException if the path is null * @throws IllegalStateException if the file is closed or it is a leaf node */ VirtualFile getChild(String path) throws IOException /** * Get the children * * @return the children * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ List getChildren() throws IOException /** * Get the children * * @param filter to filter the children * @return the children * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed or it is a leaf node */ List getChildren(VirtualFileFilter filter) throws IOException /** * Get all the children recursively * * This always uses {@link VisitorAttributes#RECURSE} * * @return the children * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ List getChildrenRecursively() throws IOException /** * Get all the children recursively * * This always uses {@link VisitorAttributes#RECURSE} * * @param filter to filter the children * @return the children * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed or it is a leaf node */ List getChildrenRecursively(VirtualFileFilter filter) throws IOException /** * Visit the virtual file system * * @param visitor the visitor * @throws IOException for any problem accessing the virtual file system * @throws IllegalArgumentException if the visitor is null * @throws IllegalStateException if the file is closed */ void visit(VirtualFileVisitor visitor) throws IOException } As you can see you have all of the usual read-only File System operations, plus a few options to cleanup or delete the resource. Cleanup or deletion handling is needed when we're dealing with some internal temporary files; e.g. from nested jars handling. To switch from JDK's File or URL resource handling to new VirtualFile we need a root. It is the VFS class that knows how to create one with the help of URL or URI parameter. public class VFS { /** * Get the virtual file system for a root uri * * @param rootURI the root URI * @return the virtual file system * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL is null */ static VFS getVFS(URI rootURI) throws IOException /** * Create new root * * @param rootURI the root url * @return the virtual file * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL */ static VirtualFile createNewRoot(URI rootURI) throws IOException /** * Get the root virtual file * * @param rootURI the root uri * @return the virtual file * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL is null */ static VirtualFile getRoot(URI rootURI) throws IOException /** * Get the virtual file system for a root url * * @param rootURL the root url * @return the virtual file system * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL is null */ static VFS getVFS(URL rootURL) throws IOException /** * Create new root * * @param rootURL the root url * @return the virtual file * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL */ static VirtualFile createNewRoot(URL rootURL) throws IOException /** * Get the root virtual file * * @param rootURL the root url * @return the virtual file * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL */ static VirtualFile getRoot(URL rootURL) throws IOException /** * Get the root file of this VFS * * @return the root * @throws IOException for any problem accessing the VFS */ VirtualFile getRoot() throws IOException } You can see three different methods that look a lot alike - getVFS, createNewRoot and getRoot. Method getVFS returns a VFS instance, and what's important, it doesn't yet create a VirtualFile instance. Why is this important? Because there are methods which help us configure a VFS instance (see VFS class API javadocs), before telling it to create a VirtualFile root. The other two methods, on the other hand, use default settings for root creation. The difference between createNewRoot and getRoot is in caching details, which we'll delve in later on. URL rootURL = ...; // get root url VFS vfs = VFS.getVFS(rootURL); // configure vfs instance VirtualFile root1 = vfs.getRoot(); // or you can get root directly VirtualFile root2 = VFS.crateNewRoot(rootURL); VirtualFile root3 = VFS.getRoot(rootURL); The other useful thing about VFS API is its implementation of a proper visitor pattern. This way it's very simple to recursively gather different resources, something quite impossible to do with plain JDK resource loading. public interface VirtualFileVisitor { /** * Get the search attribues for this visitor * * @return the attributes */ VisitorAttributes getAttributes(); /** * Visit a virtual file * * @param virtualFile the virtual file being visited */ void visit(VirtualFile virtualFile); } VirtualFile root = ...; // get root VirtualFileVisitor visitor = new SuffixVisitor(".class"); // get all classes root.visit(visitor); VFS Architecture While public API is quite intuitive, real implementation details are a bit more complex. We'll try to explain the concepts in a quick pass. Each time you create a VFS instance, its matching VFSContext instance is created. This creation is done via VFSContextFactory. Different protocols map to different VFSContextFactory instances - e.g. file/vfsfile map to FileSystemContextFactory, zip/vfszip map to ZipEntryContextFactory. Also, each time a VirtualFile instance is created, its matching VirtualFileHandler is created. It's this VirtualFileHandler instance that knows how to handle different resource types properly - VirtualFile API just delegates invocations to its VirtualFileHandler reference. As one could expect, VFSContext instance is the one that knows how to create VirtualFileHandler instances accordingly to a resource type - e.g. ZipEntryContextFactory creates ZipEntryContext, which then creates ZipEntryHandler. Existing implementations Apart from files, directories (FileHandler) and zip archives (ZipEntryHandler) we also support other more exotic usages. The first one is Assembled, which is similar to what Eclipse calls Linked Resources. Its idea is to take existing resources from different trees, and "mock" them into single resource tree. AssembledDirectory sar = AssembledContextFactory.getInstance().create("assembled.sar"); URL url = getResource("/vfs/test/jar1.jar"); VirtualFile jar1 = VFS.getRoot(url); sar.addChild(jar1); url = getResource("/tmp/app/ext.jar"); VirtualFile ext1 = VFS.getRoot(url); sar.addChild(ext); AssembledDirectory metainf = sar.mkdir("META-INF"); url = getResource("/config/jboss-service.xml"); VirtualFile serviceVF = VFS.getRoot(url); metainf.addChild(serviceVF); AssembledDirectory app = sar.mkdir("app.jar"); url = getResource("/app/someapp/classes"); VirtualFile appVF = VFS.getRoot(url); app.addPath(appVF, new SuffixFilter(".class")); Another implementation is in-memory files. In our case this came out of a need to easily handle AOP generated bytes. Instead of mucking around with temporary files, we simply drop bytes into in-memory VirtualFileHandlers. URL url = new URL("vfsmemory://aopdomain/org/acme/test/Test.class"); byte[] bytes = ...; // some AOP generated class bytes MemoryFileFactory.putFile(url, bytes); VirtualFile classFile = VFS.getVirtualFile(new URL("vfsmemory://aopdomain"), "org/acme/test/Test.class"); InputStream bis = classFile.openStream(); // e.g. load class from input stream Extension hooks It's quite easy to extend VFS with a new protocol, similar to what we've done with Assembled and Memory. All you need is a combination of VFSContexFactory, VFSContext, VirtualFileHandler, FileHandlerPlugin and URLStreamHandler implementations. The first one is trivial, while the others depend on the complexity of your task - e.g. you could implement rar, tar, gzip or even remote access. In the end you simply register this new VFSContextFactory with VFSContextFactoryLocator. See this article's demo for a simple gzip example Features One of the first major problems we stumbled upon was proper usage of nested resources, more exactly nested jar files. e.g. normal ear deployments: gema.ear/ui.war/WEB-INF/lib/struts.jar In order to read contents of struts.jar we have two options: handle resources in memory create top level temporary copies of nested jars, recursively The first option is easier to implement, but it's very memory-consuming--just imagine huge apps in memory. The other approach leaves a bunch of temporary files, which should be invisible to plain user. Hence expecting them to disappear once the deployment is undeployed. Now imagine the following scenario: A user gets a hold of VFS's URL instance, which points to some nested resource. The way plain VFS would handle this is to re-create the whole path from scratch, meaning it would unpack nested resources over and over again. This would (and it did) lead to a huge pile of temporary files. How to avoid this? The way we approached this is by using VFSRegistry, VFSCache and TempInfo. When you ask for VirtualFile over VFS (getRoot, not createNewRoot), VFS asks VFSRegistry implementation to provide the file. Existing DefaultVFSRegistry first checks if matching root VFSContext for provided URI exists. If it does, it first tries to navigate to existing TempInfo (link to temporary files), falling back to regular navigation if no such temporary file exists. This way we completely re-use any already unpacked temporary files, saving time and disk space. If no matching VFSContext is found in cache, we create a new VFSCache entry, and continue with default navigation. It's then up to VFSCache implementation used, how it handles cached VFSContext entries. VFSCache is configurable via VFSCacheFactory - by default we don't cache anything, but there are a few useful existing VFSCache implementations, ranging from LRU to timed cache. API Use case There is a class called VFSUtils which is part of a public API, and it is sort of a dumping ground of useful functionality. It contains a bunch of helpful methods and configuration settings (system property keys, actually). Check the API javadocs for more details. Existing issues / workarounds Another issue that came up - expectedly - was inability of some frameworks to properly work on top of VFS. The problem lied in custom VFS urls like: vfsfile, vfszip, vfsmemory. In most cases you could still work around it with plain URL or URLConnection usage, but a lot of frameworks do a strict match on file or jar protocol, which of course fails. We were able to patch some frameworks (e.g. Facelets) and provide extensions to others (e.g. Spring). If you are a library developer, and your library has a simple pluggable resource loading mechanism, then we suggest you simply extend it with VFS based implementation. If there are no hooks, try to limit your assumptions to more general usage based on URL or URLConnection. Conclusion While VFS is very nice to use, it comes at a price. It adds additional layer on top of JDK's resource handling, meaning extra invocations are always present when you're dealing with resources. We also keep some of the jar handling info in memory to make it easy to get hold of a specific resource, but at the expense of some extra memory consumption. Overall VFS proved to be a very useful library as it hides away many use cases that are painful with plain JDK, and provides a comprehensive API for working with resources - i.e. visitor pattern implementation. We're constantly following user feedback to VFS issues they encounter, making each version a bit better. Now, that we got to know VFS, it's time we move on to MC's new Classloading layer! About the Author Ales Justin was born in Ljubljana, Slovenia and graduated with a degree in mathematics from the University of Ljubljana. He fell in love with Java seven years ago and has spent most of his time developing information systems, ranging from customer service to energy management. He joined JBoss in 2006 to work full time on the Microcontainer project, currently serving as its lead. He also contributes to JBoss AS and is Seam and Spring integration specialist. He represent JBoss on 'JSR-291 Dynamic Component Support for Java SE' and 'OSGi' expert groups.
September 24, 2009
by Ales Justin
· 43,279 Views
article thumbnail
Sorting Collections in Hibernate Using SQL in @OrderBy
When you have collections of associated objects in domain objects, you generally want to specify some kind of default sort order. For example, suppose I have domain objects Timeline and Event: @Entity class Timeline { @Required String description @OneToMany(mappedBy = "timeline") @javax.persistence.OrderBy("startYear, endYear") Set events } @Entity class Event { @Required Integer startYear Integer endYear @Required String description @ManyToOne Timeline timeline } In the above example I've used the standard JPA (Java Persistence API) @OrderBy annotation which allows you to specify the order of a collection of objects via object properties, in this example a @OneToMany association . I'm ordering first by startYear in ascending order and then by endYear, also in ascending order. This is all well and good, but note that I've specified that only the start year is required. (The @Required annotation is a custom Hibernate Validator annotation which does exactly what you would expect.) How are the events ordered when you have several events that start in the same year but some of them have no end year? The answer is that it depends on how your database sorts null values by default. Under Oracle 10g nulls will come last. For example if two events both start in 2001 and one of them has no end year, here is how they are ordered: 2001 2002 Some event 2001 2003 Other event 2001 Event with no end year What if you want to control how null values are ordered so they come first rather than last? In Hibernate there are several ways you could do this. First, you could use the Hibernate-specific @Sort annotation to perform in-memory (i.e. not in the database) sorting, using natural sorting or sorting using a Comparator you supply. For example, assume I have an EventComparator helper class that implements Comparator. I could change Timeline's collection of events to look like this: @OneToMany(mappedBy = "timeline") @org.hibernate.annotations.Sort(type = SortType.COMPARATOR, comparator = EventCompator) Set events Using @Sort will perform sorting in-memory once the collection has been retrieved from the database. While you can certainly do this and implement arbitrarily complex sorting logic, it's probably better to sort in the database when you can. So we now need to turn to Hibernate's @OrderBy annotation, which lets you specify a SQL fragment describing how to perform the sort. For example, you can change the events mapping to : @OneToMany(mappedBy = "timeline") @org.hibernate.annotations.OrderBy("start_year, end_year") Set events This sort order is the same as using the JPA @OrderBy with "startYear, endYear" sort order. But since you write actual SQL in Hibernate's @OrderBy you can take advantage of whatever features your database has, at the possible expense of portability across databases. As an example, Oracle 10g supports using a syntax like "order by start_year, end_year nulls first" to order null end years before non-null end years. You could also say "order by start_year, end year nulls last" which sorts null end years last as you would expect. This syntax is probably not portable, so another trick you can use is the NVL function, which is supported in a bunch of databases. You can rewrite Timeline's collection of events like so: @OneToMany(mappedBy = "timeline") @org.hibernate.annotations.OrderBy("start_year, nvl(end_year , start_year)") Set events The expression "nvl(end_year , start_year)" simply says to use end_year as the sort value if it is not null, and start_year if it is null. So for sorting purposes you end up treating end_year as the same as the start_year if end_year is null. In the contrived example earlier, applying the nvl-based sort using Hibernate's @OrderBy to specify SQL sorting criteria, you now end with the events sorted like this: 2001 Event with no end year 2001 2002 Some event 2001 2003 Other event Which is what you wanted in the first place. So if you need more complex sorting logic than what you can get out of the standard JPA @javax.persistence.OrderBy, try one of the Hibernate sorting options, either @org.hibernate.annotations.Sort or @org.hibernate.annotations.OrderBy. Adding a SQL fragment into your domain class isn't necessarily the most elegant thing in the world, but it might be the most pragmatic thing.
September 16, 2009
by Scott Leberknight
· 102,197 Views
article thumbnail
Java Performance Tuning, Profiling, and Memory Management
Get a perspective on the aspects of JVM internals, controls, and switches that can be used to optimize your Java application.
September 1, 2009
by Vikash Ranjan
· 257,683 Views · 17 Likes
article thumbnail
JPA Implementation Patterns: Lazy Loading
Model your complete database with all its relations with this JPA pattern for lazy loading.
August 19, 2009
by Vincent Partington
· 120,389 Views · 6 Likes
article thumbnail
Spring Integration: A Hands-On Tutorial, Part 1
This tutorial is the first in a two-part series on Spring Integration. In this series we're going to build out a lead management system based on a message bus that we implement using Spring Integration. Our first tutorial will begin with a brief overview of Spring Integration and also just a bit about the lead management domain. After that we'll build our message bus. The second tutorial continues where the first leaves off and builds the rest of the bus. I’ve written the sample code for this tutorial as a Maven 2 project. I’m using Java 5, Spring Integration 1.0.3 and Spring 2.5.6. The code also works for Java 6. I've used Maven profiles to isolate the dependencies you’ll need if you’re running Java 5. The tutorials assume that you're comfortable with JEE, the core Spring framework and Maven 2. Also, Eclipse users may find the m2eclipse plug-in helpful. To complete the tutorial you'll need an IMAP account, and you'll also need access to an SMTP server. Let's begin with an overview of Spring Integration. A bird's eye view of Spring Integration Spring Integration is a framework for implementing a dynamically configurable service integration tier. The point of this tier is to orchestrate independent services into meaningful business solutions in a loosely-coupled fashion, which makes it easy to rearrange things in the face of changing business needs. The service integration tier sits just above the service tier as shown in figure 1. Following the book Enterprise Integration Patterns by Gregor Hohpe and Bobby Woolf (Addison-Wesley), Spring Integration adopts the well-known pipes and filters architectural style as its approach to building the service integration layer. Abstractly, filters are information-processing units (any type of processing—doesn’t have to be information filtering per se), and pipes are the conduits between filters. In the context of integration, the network we’re building is a messaging infrastructure—a so-called message bus—and the pipes and filters and called message channels and message endpoints, respectively. The network carries messages from one endpoint to another via channels, and the message is validated, routed, split, aggregated, resequenced, reformatted, transformed and so forth as the different endpoints process it. Figure 1. The service integration tier orchestrates the services below it. That should give you enough technical context to work through the tutorial. Let’s talk about the problem domain for our sample integration, which is enrollment lead management in an online university setting. Lead management overview In many industries, such as the mortgage industry and for-profit education, one important component of customer relationship management (CRM) is managing sales leads. This is a fertile area for enterprise integration because there are typically multiple systems that need to play nicely together in order to pull the whole thing off. Examples include front-end marketing/lead generation websites, external lead vendor systems, intake channels for submitted leads, lead databases, e-mail systems (e.g., to accept leads, to send confirmation e-mails), lead qualification systems, sales systems and potentially others. This tutorial and the next use Spring Integration to integrate several of systems of the kind just mentioned into an overall lead management capability for a hypothetical online university. Specifically we’ll integrate the following: • a CRM system that allows campus and call center staff to create leads directly, as they might do for walk-in or phone-in leads • a Request For Information (RFI) form on a lead generation ("lead gen") marketing website • a legacy e-mail based RFI channel • an external CRM that the international enrollment staff uses to process international leads • confirmation e-mails Figure 2 shows what it will look like when we’re done with both tutorials. For now focus on the big picture rather than the details. Figure 2. This is the lead management system we'll build. For this first tutorial we're simply going to establish the base staff interface, the (dummy) backend service that saves leads to a database, and confirmation e-mails. The second tutorial will deal with lead routing, web-based RFIs and e-mail-based RFIs. Let's dive in. We’ll begin with the basic lead creation page in the CRM and expand out from there. Building the core components [You can download the source code for this section of the tutorial here] We’re going to start by creating a lead creation HTML form for campus and call center staff. That way, if walk-in or phone-in leads express an interest, we can get them into the system. This is something that might appear as a part of a lead management module in a CRM system, as shown in figure 3. Figure 3. We'll build our lead management module with integration in mind from the beginning. Because we’re interested in the integration rather than the actual app features, we’re not really going to save the lead to the database. Instead we’ll just call a createLead() method against a local LeadService bean and leave it at that. But we will use Spring Integration to move the lead from the form to the service bean. Our first stop will be the domain model. DZone readers get 30% off Spring in Practice by Willie Wheeler and John Wheeler. Use code dzone30 when checking out with any version of the book at www.manning.com. Create the domain model We’ll need a domain object for leads, so listing 1 shows the one we’ll use. It’s not an industrial-strength representation, but it will do for the purposes of the tutorial. Listing 1. Lead.java, a basic domain object for leads. package crm.model;... other imports ...public class Lead { private static DateFormat dateFormat = new SimpleDateFormat(); private String firstName; private String middleInitial; private String lastName; private String address1; private String address2; ... other fields ... public Lead() { } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } ... other getters and setters, and a toString() method ...} There is nothing special happening here at all. So far the Lead class is just a bunch of getters and setters. You can see the full code listing in the download. If you thought that was underwhelming, just wait until you see the LeadServiceImpl service bean in listing 2. Listing 2. LeadServiceImpl.java, a dummy service bean. package crm.service;import java.util.logging.Logger;import org.springframework.stereotype.Service;import crm.model.Lead;@Service("leadService")public class LeadServiceImpl implements LeadService { private static Logger log = Logger.getLogger("global"); public void createLead(Lead lead) { log.info("Creating lead: " + lead); } This is just a dummy bean. In real life we’d save the lead to a database. The bean implements a basic LeadService interface that we've suppressed here, but it's available in the code download. Now that we have our domain model, let’s use Spring Integration to create a service integration tier above it. Create the service integration tier If you look back at figure 3, you’ll see that the CRM app pushes lead data to the service bean by way of a channel called newLeadChannel. While it’s possible for the CRM app to push messages onto the channel directly, it’s generally more desirable to keep the systems you’re integrating decoupled from the underlying messaging infrastructure, such as channels. That allows you to configure service orchestrations dynamically instead of having to go into the code. Spring Integration supports the Gateway pattern (described in the aforementioned Enterprise Integration Patterns book), which allows an application to push messages onto the message bus without knowing anything about the messaging infrastructure. Listing 3 shows how we do this. Listing 3. LeadGateway.java, a gateway offering access to the messaging system. package crm.integration.gateways;import org.springframework.integration.annotation.Gateway;import crm.model.Lead;public interface LeadGateway { @Gateway(requestChannel = "newLeadChannel") void createLead(Lead lead);} We are of course using the Spring Integration @Gateway annotation to map the method call to the newLeadChannel, but gateway clients don’t know that. Spring Integration will use this interface to create a dynamic proxy that accepts a Lead instance, wraps it with an org.springframework.integration.core.Message, and then pushes the Message onto the newLeadChannel. The Lead instance is the Message body, or payload, and Spring Integration wraps the Lead because only Messages are allowed on the bus. We need to wire up our message bus. Figure 4 shows how to do that with an application context configuration file. Listing 4. /WEB-INF/applicationContext-integration.xml message bus definition. The first thing to notice here is that we've made the Spring Integration namespace our default namespace instead of the standard beans namespace. The reason is that we're using this configuration file strictly for Spring Integration configuration, so we can save some keystrokes by selecting the appropriate namespace. This works pretty nicely for some of the other Spring projects as well, such as Spring Batch and Spring Security. In this configuration we've created the three messaging components that we saw in figure 3. First, we have an incoming lead gateway to allow applications to push leads onto the bus. We simply reference the interface from listing 3; Spring Integration takes care of the dynamic proxy. Next we create a publish/subscribe ("pub-sub") channel called newLeadChannel. This is the channel that the @Gateway annotation referenced in listing 3. A pub-sub channel can publish a message to multiple endpoints simultaneously. For now we have only one subscriber—a service activator—but we already know we're going to have others, so we may as well make this a pub-sub channel. The service activator is an endpoint that allows us to bring our LeadServiceImpl service bean onto the bus. We're injecting the newLeadChannel into the input end of the service activator. When a message appears on the newLeadChannel, the service activator will pass its Lead payload to the leadService bean's createLead() method. Stepping back, we've almost implemented the design described by figure 3. The only part that remains is the lead creation frontend, which we'll address right now. Create the web tier Our user interface for creating new leads will be a web-based form that we implement using Spring Web MVC. The idea is that enrollment staff at campuses or call centers might use such an interface to handle walk-in or phone-in traffic. Listing 5 shows our simple @Controller. Listing 5. LeadController.java, a @Controller to allow staff to create leads package crm.web;import java.util.Date;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import crm.integration.gateways.LeadGateway;import crm.model.Country;import crm.model.Lead;@Controllerpublic class LeadController { @Autowired private LeadGateway leadGateway; @RequestMapping(value = "/lead/form.html", method = RequestMethod.GET) public void getForm(Model model) { model.addAttribute(Country.getCountries()); model.addAttribute(new Lead()); } @RequestMapping(value = "/lead/form.html", method = RequestMethod.POST) public String postForm(Lead lead) { lead.setDateCreated(new Date()); leadGateway.createLead(lead); return "redirect:form.html?created=true"; } This isn't an industrial-strength controller as it doesn't do HTTP parameter whitelisting (for example, via an @InitBinder method) and form validation, both of which you would expect from a real implementation. But the main pieces from a Spring Integration perspective are here. We're autowiring the gateway into the @Controller, and we have methods for serving up the empty form and for processing the submitted form. The getForm() method references a Countries class that we've suppressed (it's in the code download); it just puts a list of countries on the model so the form can present a Country field to the staff member. The postForm() method invokes the createLead() method on the gateway. This will pass the Lead to the dynamic proxy LeadGateway implementation, which in turn will wrap the Lead with a Message and then place the Message on the newLeadChannel. There are a few other configuration files you will need to put in place, including web.xml, main-servlet.xml and applicationContext.xml. There's also a JSP for the web form. As none of these relates directly to Spring Integration, we won't treat them here. Please see the code download for details. With that, we've established a baseline system. To try it out, run mvn jetty:run against crm/pom.xml and point your browser at http://localhost:8080/crm/main/lead/form.html You should see a very basic-looking web form for entering lead information. Enter some user information (it doesn't matter what you enter—recall that we don't have any form validation) and press Submit. The console should report that LeadServiceImpl.createLead() created a lead. Congratulations! Even though we now have a working system, it isn't very interesting. From here on out (this tutorial and the next) we'll be adding some common features to make the lead management system more capable. Our first addition will be confirmation e-mails; the next tutorial will present further additions. Adding confirmation e-mails [The source for this section is available here] After an enrollment advisor (or some other staff member) creates a lead in the system, we want to send the lead an e-mail letting him know that that's happened. Actually—and this is a critical point—we really don't care how the lead was created. Anytime a lead appears on the newLeadChannel, we want to fire off a confirmation e-mail. I'm making the distinction because it points to an important aspect of the message bus: it allows us to control lead processing code centrally instead of having to chase it down in a bunch of different places. Right now there's only one way to create leads, but figure 2 revealed that we'll be adding others. No matter how many we add, they'll all result in sending a confirmation e-mail out to the lead. Figure 4 shows the new bit of plumbing we're going to add to our message bus. Figure 4. Send a confirmation e-mail when creating a lead. To do this, we're going to need to make a few changes to the configuration and code. POM changes First we need to update the POM. Here's a summary of the changes; see the code download for details: • Add a JavaMail dependency to the Jetty plug-in. • Add an org.springframework.context.support dependency. • Add a spring-integration-mail dependency. • Set the mail.version property. These changes will allow us to use JavaMail. Expose JavaMail sessions through JNDI We'll also need to add a /WEB-INF/jetty-env.xml configuration to make our JavaMail sessions available via JNDI. Once again, see the code download for details. I've included a /WEB-INF/jetty-env.xml.sample configuration for your convenience. As mentioned previously, you'll need access to an SMTP server. Besides creating jetty-env.xml, we'll need to update applicationContext.xml. Listing 6 shows the changes we need so we can use JavaMail and SMTP. Listing 6. /WEB-INF/applicationContext.xml changes supporting JavaMail and SMTP The changes expose JavaMail sessions as a JNDI resource. We've declared the jee namespace and its schema location, configured the JNDI lookup, and created a JavaMailSenderImpl bean that we'll use for sending mail. We won't need any domain model changes to generate confirmation e-mails. We will however need to create a bean to back our new transformer endpoint. Service integration tier changes First, recall from figure 4 that the newLeadChannel feeds into a LeadToEmailTransformer endpoint. This endpoint takes a lead as an input and generates a confirmation e-mail as an output, and the e-mail gets pipes out to an SMTP transport. In general, transformers transform given inputs into desired outputs. No surprises there. Figure 4 is slightly misleading since it's actually the POJO itself that we're going to call LeadToEmailTransformer; the endpoint is really just a bean adapter that the messaging infrastructure provides so we can place the POJO on the message bus. Listing 7 presents the LeadToEmailTransformer POJO. Listing 7. LeadToEmailTransformer.java, a POJO to generate confirmation e-mails package crm.integration.transformers;import java.util.Date;import java.util.logging.Logger;import org.springframework.integration.annotation.Transformer;import org.springframework.mail.MailMessage;import org.springframework.mail.SimpleMailMessage;import crm.model.Lead;public class LeadToEmailTransformer { private static Logger log = Logger.getLogger("global"); private String confFrom; private String confSubj; private String confText; ... getters and setters for the fields ... @Transformer public MailMessage transform(Lead lead) { log.info("Transforming lead to confirmation e-mail: " + lead); String leadFullName = lead.getFullName(); String leadEmail = lead.getEmail(); MailMessage msg = new SimpleMailMessage(); msg.setTo(leadFullName == null ? leadEmail : leadFullName + " <" + leadEmail + ">"); msg.setFrom(confFrom); msg.setSubject(confSubj); msg.setSentDate(new Date()); msg.setText(confText); log.info("Transformed lead to confirmation e-mail: " + msg); return msg; } Again, LeadToEmailTransformer is a POJO, so we use the @Transformer annotation to select the method that's performing the transformation. We use a Lead for the input and a MailMessage for the output, and perform a simple transformation in between. When defining backing beans for the various Spring Integration filters, it's possible to specify a Message as an input or an output. That is, if we want to deal with the messages themselves rather than their payloads, we can do that. (Don't confuse the MailMessage in listing 7 with a Spring Integration message; MailMessage represents an e-mail message, not a message bus message.) We might do that in cases where we want to read or manipulate message headers. In this tutorial we don't need to do that, so our backing beans just deal with payloads. Now we'll need to build out our message bus so that it looks like figure 4. We do this by updating applicationContext-integration.xml as shown in listing 8. Listing 8. /WEB-INF/applicationContext-integration.xml updates to support confirmation e-mails The property-placeholder configuration loads the various ${...} properties from a properties file; see /crm/src/main/resources/applicationContext.properties in the code download. You don't have to change anything in the properties file. The transformer configuration brings the LeadToEmailTransformer bean into the picture so it can transform Leads that appear on the newLeadChannel into MailMessages that it puts on the confEmailChannel. As a side note, the p namespace way of specifying bean properties doesn't seem to work here (I assume it's a bug: http://jira.springframework.org/browse/SPR-5990), so I just did it the more verbose way. The channel definition defines a point-to-point channel rather than a pub-sub channel. That means that only one endpoint can pull messages from the channel. Finally we have an outbound-channel-adapter that grabs MailMessages from the confEmailChannel and then sends them using the referenced mailSender, which we defined in listing 6. That's it for this section. We should have working confirmation e-mails. Restart your Jetty instance and go again to http://localhost:8080/crm/main/lead/form.html Fill it out and provide your real e-mail address in the e-mail field. A few moments after submitting the form you should receive a confirmation e-mail. If you don't see it, you might check your SMTP configuration in jetty-env.xml, or else check your spam folder. Summary In this tutorial we've taken our first steps toward developing an integrated lead management system. Though the current bus configuration is simple, we've already seen some key Spring Integration features, including • support for the Gateway pattern, allowing us to connect apps to the message bus without knowing about messages • point-to-point and pub-sub channels • service activators to allow us to place service beans on the bus • message transformers • outbound SMTP channel adapters to allow us to send e-mail The second tutorial will continue elaborating what we've developed here, demonstrating the use of several additional Spring Integration features, including • message routers (including content-based message routers) • outbound web service gateways for sending SOAP messages • inbound HTTP adapters for collecting HTML form data from external systems • inbound e-mail channel adapters (we'll use IMAP IDLE, though POP and IMAP are also possible) for processing incoming e-mails Enjoy, and stay tuned. Willie is a solutions architect with 12 years of Java development experience. He and his brother John are coauthors of the upcoming book Spring in Practice by Manning Publications (www.manning.com/wheeler/). Willie also publishes technical articles (including many on Spring) to wheelersoftware.com/articles/.
August 18, 2009
by Willie Wheeler
· 249,399 Views · 3 Likes
article thumbnail
JPA 2.0 Concurrency and Locking
Optimistic locking lets concurrent transactions process simultaneously, but detects and prevent collisions, this works best for applications where most concurrent transactions do not conflict. JPA Optimistic locking allows anyone to read and update an entity, however a version check is made upon commit and an exception is thrown if the version was updated in the database since the entity was read. In JPA for Optimistic locking you annotate an attribute with @Version as shown below: public class Employee { @ID int id; @Version int version; The Version attribute will be incremented with a successful commit. The Version attribute can be an int, short, long, or timestamp. This results in SQL like the following: “UPDATE Employee SET ..., version = version + 1 WHERE id = ? AND version = readVersion” The advantages of optimistic locking are that no database locks are held which can give better scalability. The disadvantages are that the user or application must refresh and retry failed updates. Optimistic Locking Example In the optimistic locking example below, 2 concurrent transactions are updating employee e1. The transaction on the left commits first causing the e1 version attribute to be incremented with the update. The transaction on the right throws an OptimisticLockException because the e1 version attribute is higher than when e1 was read, causing the transaction to roll back. Additional Locking with JPA Entity Locking APIs With JPA it is possible to lock an entity, this allows you to control when, where and which kind of locking to use. JPA 1.0 only supported Optimistic read or Optimistic write locking. JPA 2.0 supports Optimistic and Pessimistic locking, this is layered on top of @Version checking described above. JPA 2.0 LockMode values : OPTIMISTIC (JPA 1.0 READ): perform a version check on locked Entity before commit, throw an OptimisticLockException if Entity version mismatch. OPTIMISTIC_FORCE_INCREMENT (JPA 1.0 WRITE) perform a version check on locked Entity before commit, throw an OptimisticLockException if Entity version mismatch, force an increment to the version at the end of the transaction, even if the entity is not modified. PESSIMISTIC: lock the database row when reading PESSIMISTIC_FORCE_INCREMENT lock the database row when reading, force an increment to the version at the end of the transaction, even if the entity is not modified. There are multiple APIs to specify locking an Entity: EntityManager methods: lock, find, refresh Query methods: setLockMode NamedQuery annotation: lockMode element OPTIMISTIC (READ) LockMode Example In the optimistic locking example below, transaction1 on the left updates the department name for dep , which causes dep's version attribute to be incremented. Transaction2 on the right gives an employee a raise if he's in the "Eng" department. Version checking on the employee attribute would not throw an exception in this example since it was the dep Version attribute that was updated in transaction1. In this example the employee change should not commit if the department was changed after reading, so an OPTIMISTIC lock is used : em.lock(dep, OPTIMISTIC). This will cause a version check on the dep Entity before committing transaction2 which will throw an OptimisticLockException because the dep version attribute is higher than when dep was read, causing the transaction to roll back. OPTIMISTIC_FORCE_INCREMENT (write) LockMode Example In the OPTIMISTIC_FORCE_INCREMENT locking example below, transaction2 on the right wants to be sure that the dep name does not change during the transaction, so transaction2 locks the dep Entity em.lock(dep, OPTIMISTIC_FORCE_INCREMENT) and then calls em.flush() which causes dep's version attribute to be incremented in the database. This will cause any parallel updates to dep to throw an OptimisticLockException and roll back. In transaction1 on the left at commit time when the dep version attribute is checked and found to be stale, an OptimisticLockException is thrown Pessimistic Concurrency Pessimistic concurrency locks the database row when data is read, this is the equivalent of a (SELECT . . . FOR UPDATE [NOWAIT]) . Pessimistic locking ensures that transactions do not update the same entity at the same time, which can simplify application code, but it limits concurrent access to the data which can cause bad scalability and may cause deadlocks. Pessimistic locking is better for applications with a higher risk of contention among concurrent transactions. The examples below show: reading an entity and then locking it later reading an entity with a lock reading an entity, then later refreshing it with a lock The Trade-offs are the longer you hold the lock the greater the risks of bad scalability and deadlocks. The later you lock the greater the risk of stale data, which can then cause an optimistic lock exception, if the entity was updated after reading but before locking. The right locking approach depends on your application: what is the risk of risk of contention among concurrent transactions? What are the requirements for scalability? What are the requirements for user re-trying on failure? For More Information: Preventing Non-Repeatable Reads in JPA Using EclipseLink Java Persistence API 2.0: What's New ? What's New and Exciting in JPA 2.0 Beginning Java™ EE 6 Platform with GlassFish™ 3 Pro EJB 3: Java Persistence API (JPA 1.0)
August 3, 2009
by Carol McDonald
· 51,399 Views · 1 Like
article thumbnail
Autocomplete Combobox In Java With Filtering And Inserting New Text
import java.awt.EventQueue; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.List; import javax.swing.AbstractListModel; import javax.swing.ComboBoxModel; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.Timer; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.JTextComponent; import javax.swing.text.PlainDocument; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; /** * Autocomplete combobox with filtering and * text inserting of new text * @author Exterminator13 */ public class AutoCompleteCombo extends JComboBox{ private static final Logger logger = Logger.getLogger(AutoCompleteCombo.class); private Model model = new Model(); private final JTextComponent textComponent = (JTextComponent) getEditor().getEditorComponent(); private boolean modelFilling = false; private boolean updatePopup; public AutoCompleteCombo() { setEditable(true); logger.debug("setPattern() called from constructor"); setPattern(null); updatePopup = false; textComponent.setDocument(new AutoCompleteDocument()); setModel(model); setSelectedItem(null); new Timer(20, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (updatePopup && isDisplayable()) { setPopupVisible(false); if (model.getSize() > 0) { setPopupVisible(true); } updatePopup = false; } } }).start(); } private class AutoCompleteDocument extends PlainDocument { boolean arrowKeyPressed = false; public AutoCompleteDocument() { textComponent.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if (key == KeyEvent.VK_ENTER) { logger.debug("[key listener] enter key pressed"); //there is no such element in the model for now String text = textComponent.getText(); if (!model.data.contains(text)) { logger.debug("addToTop() called from keyPressed()"); addToTop(text); } } else if (key == KeyEvent.VK_UP || key == KeyEvent.VK_DOWN) { arrowKeyPressed = true; logger.debug("arrow key pressed"); } } }); } void updateModel() throws BadLocationException { String textToMatch = getText(0, getLength()); logger.debug("setPattern() called from updateModel()"); setPattern(textToMatch); } @Override public void remove(int offs, int len) throws BadLocationException { if (modelFilling) { logger.debug("[remove] model is being filled now"); return; } super.remove(offs, len); if (arrowKeyPressed) { arrowKeyPressed = false; logger.debug("[remove] arrow key was pressed, updateModel() was NOT called"); } else { logger.debug("[remove] calling updateModel()"); updateModel(); } clearSelection(); } @Override public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { if (modelFilling) { logger.debug("[insert] model is being filled now"); return; } // insert the string into the document super.insertString(offs, str, a); // if (enterKeyPressed) { // logger.debug("[insertString] enter key was pressed"); // enterKeyPressed = false; // return; // } String text = getText(0, getLength()); if (arrowKeyPressed) { logger.debug("[insert] arrow key was pressed, updateModel() was NOT called"); model.setSelectedItem(text); logger.debug( String.format("[insert] model.setSelectedItem(%s)", text) ); arrowKeyPressed = false; } else if(!text.equals(getSelectedItem())){ logger.debug("[insert] calling updateModel()"); updateModel(); } clearSelection(); } } public void setText(String text) { if (model.data.contains(text)) { setSelectedItem(text); } else { addToTop(text); setSelectedIndex(0); } } public String getText() { return getEditor().getItem().toString(); } private String previousPattern = null; private void setPattern(String pattern) { if(pattern!=null && pattern.trim().isEmpty()) pattern = null; if(previousPattern==null && pattern ==null || pattern!=null && pattern.equals(previousPattern)) { logger.debug("[setPatter] pattern is the same as previous: "+previousPattern); return; } previousPattern = pattern; modelFilling = true; // logger.debug("setPattern(): start"); model.setPattern(pattern); if(logger.isDebugEnabled()) { StringBuilder b = new StringBuilder(100); b.append("pattern filter '").append(pattern==null ? "null" : pattern).append("' set:\n"); for(int i=0; i list = new ArrayList(limit); private List lowercase = new ArrayList(limit); private List filtered; void add(String s) { list.add(s); lowercase.add(s.toLowerCase()); } void addToTop(String s) { list.add(0, s); lowercase.add(0, s.toLowerCase()); } void remove(int index) { list.remove(index); lowercase.remove(index); } List getList() { return list; } List getFiltered() { if(filtered==null) filtered = list; return filtered; } int size() { return list.size(); } void setPattern(String pattern) { if (pattern == null || pattern.isEmpty()) { filtered = list; AutoCompleteCombo.this.setSelectedItem(model.getElementAt(0)); logger.debug( String.format("[setPattern] combo.setSelectedItem(null)") ); } else { filtered = new ArrayList(limit); pattern = pattern.toLowerCase(); for(int i=0; isize2) { fireIntervalRemoved(this, size2, size1-1); fireContentsChanged(this, 0, size2-1); } } public void addToTop(String aString) { if(aString==null || data.contains(aString)) return; if(data.size()==0) data.add(aString); else data.addToTop(aString); while(data.size()>limit) { int index = data.size()-1; data.remove(index); } setPattern(null); model.setSelectedItem(aString); logger.debug( String.format("[addToTop] model.setSelectedItem(%s)", aString) ); //saving into options if (data.size() > 0) { writeData(); } } @Override public Object getSelectedItem() { return selected; } @Override public void setSelectedItem(Object anObject) { if ((selected != null && !selected.equals(anObject)) || selected == null && anObject != null) { selected = (String) anObject; fireContentsChanged(this, -1, -1); } } @Override public int getSize() { return data.getFiltered().size(); } @Override public Object getElementAt(int index) { return data.getFiltered().get(index); } } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { // Logger root = Logger.getRootLogger(); // root.addAppender(new ConsoleAppender(new PatternLayout("%d{ISO8601} [%5p] %m at %l%n"))); Logger root = Logger.getRootLogger(); root.addAppender(new ConsoleAppender(new PatternLayout("%d{ISO8601} %m at %L%n"))); // BasicConfigurator.configure(); JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new GridLayout(3, 1)); final JLabel label = new JLabel("label "); frame.add(label); final AutoCompleteCombo combo = new AutoCompleteCombo(); // combo.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() { // // @Override // public void keyReleased(KeyEvent e) { // if (e.getKeyCode() == KeyEvent.VK_ENTER) { // String text = combo.getEditor().getItem().toString(); // if(text.isEmpty()) // return; // combo.addToTop(text); // } // } // }); frame.add(combo); JComboBox combo2 = new JComboBox(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); combo2.setEditable(true); frame.add(combo2); frame.pack(); frame.setSize( 500, frame.getHeight() ); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } }
July 25, 2009
by Snippets Manager
· 19,321 Views
article thumbnail
Android vs iPhone Development: A Comparison
A few months ago I ventured into the world of Mobile development and created an application (Hudson Helper) for both iPhone and Android. This article is about my experiences, comparing Android and iPhone development with a focus on tools, platform and the developer experience. Before going much further I should note that my comparison is with considerable bias. I’ve spent the past 12+ years in Java development, having spent much of my career building developer tools. Since January of 2004 I’ve been building plug-ins for Eclipse, and before that plug-ins for NetBeans. This bias is somewhat tempered with several years of C and C++ development. With this background I find that I’m very critical of developer tools. Developer productivity is key — anything that takes away from the flow of a developer in the zone is a real problem. Language, Programming Model and Platform Language The language of choice for iPhone development is Objective-C. Objective-C is a language based on C with extensions for object-oriented concepts, such as classes, inheritance, interfaces, messages, dynamic typing, etc. The Java language is used when developing for Android (though it doesn’t actually get compiled to bytecode). Java is a no-brainer. I have to say that it’s nice not to have to learn a new language to target mobile. Existing skillsets don’t come easy — so reuse of expertise is worth a lot. It took a little while to wrap my head around some of the language features available with Objective-C. I soon discovered that I really loved certain language features, such as message passing (instead of calling methods), categories and named arguments. I did find however that the syntax of Objective-C is cumbersome. I’m still not used to ‘+’ and ‘-’ for static and member methods, too many parentheses are required, and in general I just felt like I had to type way to much to express a simple concept. The IDE didn’t help much with this either (more on that later). One thing that really became clear to me is that Objective-C, though it may have been visionary for its time, is really a language of the '80s. Certain issues such as split header and implementation files and violation of DRY are really time-wasters, and not small ones at that. I found myself constantly switching back and forth between files, which not only has a cost in navigation (which file to open?) but with every file opened your sense of context must be recreated (where’s the caret, what’s selected, where am I in the file, how is this file organized). As far as DRY, must I really do 5 things to declare a property?? (declare in the class definition, again to declare getter/settter, initialize in the init method, @synthesize in the implementation, release in dealloc). Here’s what I mean: Server.h @interface Server : Updatable {NSString *name; <-- declare the property }@property (nonatomic,retain) NSString *name; <--- declare the property again Server.m @synthesize name; <-- implement getter/setter-(void) dealloc {[name release]; <-- release memory} If you ask me, everything in Server.m should go away. Another gotcha here is the positional relevance of @synthesize. Java has a similar problem with properties, though not quite so bad — and the IDE helps you write your getter/setter. Pointers in Objective-C, though powerful, are also another time-waster. This is where Java really shines with its garbage collection. I found that I was constantly considering whether allocated objects were freed appropriately. Code flow is poor since application logic is littered with memory management. I only have so many brain cycles available — why do I have to think about this other cruft that’s not really a core concern of the application domain? Of course this gets even worse when trying to figure out where things went wrong if you make a mistake. Zombies help, but still don’t make it obvious if you’ve accessed something that was deallocated. Other issues include deallocating something twice, autoreleasing something twice. I also found it non-intuitive when to retain return values from methods. Another annoyance of Objective-C is the patterns that must be followed: implementing correct init and dealloc methods is non-trivial. @synthesized getters and setters for properties with retain should not be called in these methods. So many conventions and rules to remember! Though I understand why there’s a separation of alloc and init, it’s still overly wordy to specify [[aloc Foo] initWithArg: arg]. Why not just [new Foo arg]? Or how about new Foo(arg) -- oh, wait, that’s just like Java! Objective-C’s imports and forward-declarations (@class) are a pain. Though these issues exist with Java development, Eclipse’s JDT is so good that I’ve almost forgotten what it’s like to write an import. All you have to do is Ctrl+Space to auto-complete a class name or Ctrl+Shift+O to organize imports and voila! Of course Java is not perfect either, however this fact is hidden from me due to the fact that I’ve been living in Java for a very long time. Sometimes I wish that Java were more Groovy-like, however I’m used to it and the tooling is so good. Platform On Android I found that I could readily use the Java runtime classes. Some, but not all, of the standard Java RT classes are available on Android. I didn’t find this a problem, since most of the standard Java IO, network and regex libraries are available. Android RT classes appear to be based on Harmony, which has been around long enough to be stable. With iPhone on the other hand, finding the functionality that I needed was painful. Classes and methods are poorly organized. When to look for a static method versus a class with members was not clear to me. Also depending on the framework used, naming conventions and code organization would differ. I suppose this is the legacy of an older platform. Areas where functionality was lacking that I found painful were regular expressions, string handling and XML parsing. I ended up using the excellent Regex Kit Lite for regular expressions. For XML parsing I implemented a parser abstraction over libxml, only to discover later that I may have had an easier time with NSXMLParser which is a lot more like SAX. On the iPhone when things didn’t work as expected I had to resort to Google and hope that others had encountered the same problem. This technique was hampered by Apple’s earlier NDA policy, which meant that iPhone content is pretty thin on the net. In some cases I would resort to guesswork and experimentation to find a solution. Android has the benefit of being open source. Within minutes I had the full Android platform source code on my system, and had re-built the SDK from sources to ensure that the source I had matched the runtime classes in the emulator. So not only could I see how things were implemented in the Android platform and learn by example, I could step through the platform code in the emulator and discover why my code wasn’t producing the desired results. In general I found the layout, organization, and naming conventions of Android platform classes was consistent and predictable. This made it much easier to learn. Programming Model The iPhone platform does a great job of encouraging an MVC design pattern. With this design pattern built in to the platform, building the UI was simple and I didn’t have to figure out how to organize the UI component design myself. It also means that when looking at sample code, it’s all organized in the same way. Android also does a good job with design patterns, though their concepts varied significantly from the iPhone. With Android’s support for multiple processes and component reuse, the platform itself provides support for Intents and Activities (an Intent is just a variant of a command). The design results in a better user experience, however it does introduce some complexity for the developer: when starting one Activity from another, an Intent is used to communicate any parameters. These parameters cannot be passed by reference — only by value. Where on the iPhone it’s simple to have screens sharing the same data structures, on Android this requires some forethought. Apparently Android applications can manage the back button and have everything occur inside a single Activity, however this is not the norm. Both Android and iPhone provide a way of declaring user preferences in XML. Both platforms provide a default UI for editing those preferences, which is great. Android’s XML format is extensible allowing custom UI components to be integrated, which makes user preferences a breeze. iPhone developers that wish to customize preferences will have to implement a UI from scratch, which is a lot more work. Testing and Continuous Integration I’m of the opinion that every development effort should include unit tests. Teams of size greater than one should also include Continuous Integration. Android developers will be happy to know that they can write JUnit tests. I could even launch these from the Eclipse UI after some classpath fiddling. Though I didn’t try it, I assume that it’s trivial to run these from Ant and your favorite CI server such as Hudson. I did see some iPhone unit test documentation with the iPhone SDK but didn’t take the time to explore it — so I can’t comment there. Resources Apple does an excellent job of providing lots of resources for developers. Important concepts are explained in videos, which makes grasping concepts easy — however I did find that videos progressed slowly and I was watching for what seemed like hours to find information that should have taken minutes. Luckily Apple also provides lots of sample applications and code to demonstrate API usage. Android developers also have access to loads of resources. The guide and API reference are installed with the SDK, so everything is available when offline (which for me is important since I do a lot of my work in transit). I found the Android development resources better organized and spent less time looking and more time finding. In particular the ApiDemos sample app provides a great starting point. I also downloaded many open source Android projects for ideas on architecture and API usage. This is an area where Android has the advantage, with Apple’s previous NDA policy there isn’t much out there in terms of open source for iPhone. Tooling For me tooling was a real shocker. These are the categories of tooling that I’ll cover: IDE, UI builder, debugger, profiler. Almost everything else is related to provisioning, and in that area I didn’t notice much in the way of differences between Android and iPhone. IDE Android development leverages the excellent JDT tools, which are pretty much stock and standard with every Eclipse installation. I’ve used these tools now for many years and they’re excellent. Everything Java is indexed, the IDE has a rich model of the source code, and refactoring is so seamless that it has changed the way that I work. Perhaps the best feature of JDT is its incremental compiler, which provides immediate feedback with errors and warnings as you type. This eliminates the code-compile-wait-for-feedback cycle that was so common in the '80s and '90s. Errors and warnings are updated in the Java editor as I type, giving me instant feedback. I didn’t realize just how valuable this feature is until I was coding Objective-C in XCode — when I became acutely aware at how waiting for compiler feedback can break the flow of programming. Other key features that make Eclipse so amazing to work with are: content assist quick-fixes organize imports open type (CTRL+Shift+T) refactorings Integrated javadoc and content assist is quite possibly the best way to learn an unfamiliar API. In Ecipse not only are all classes and methods immediately available in the context in which you’re writing code, their documentation is presented alongside. Content Assist with Integrated Javadoc XCode is so shockingly bad that I almost don’t know where to start. Here’s a minimum list of things that I think need fixing in order for XCode to become a viable IDE: Content assist that actually works. Content assist provided by XCode is often wrong, and almost always suggests a small subset of what’s actually available. A decent window/editor management system. XCode and it’s associated tools (debugger) like to open lots of windows. Want to open a file? How about a new window for you! Very quickly I found myself in open-window-hell. The operating system’s window management is designed for managing multiple applications, not multiple editors within an IDE. It’s simply not capable of providing management of editors in an environment as sophisticated as an IDE. A project tree view that sorts files alphabetically. Really! Integrated API documentation. I found that I was constantly switching out of the IDE and searching for API documentation using Appkido. This may seem trivial, but it really breaks the flow. One area of Eclipse that simply can’t be matched is Mylyn. Integrated task management and a focused interface introduce huge efficiencies into any project, small or large. If you haven’t yet tried out Mylyn, it’s definitely worth your time to take a look. A good place to start is Mylyn’s Getting Started page. UI Builder iPhone app developers are given a pretty good UI builder. It does a great job of showing the UI as it will actually appear. It’s flexible and can model some pretty sophisticated UIs, so I was impressed. I found that using it was a little tricky — I had to read the documentation two or three times before I could really figure out how to use it properly. The Android UI builder I found pretty useless: it can’t display UIs how they’ll actually appear, and it’s UI is way too inefficient. I found that I coded all of the UIs directly in the XML source view of the UI builder. There the content assist and validation were pretty good, making it the easiest way for me to build a UI. Debugger Having used to the Java debugger in Eclipse I was shocked at the state of the debugger in XCode. With Eclipse I can see and modify variable values. Not so in XCode. Maybe this is simply the state of affairs when debugging native code, but it sure affects the usefulness of the debugger. XCode often seemed confused as to the type of an object and presented me with a pointer value and no detail. This is a sharp contrast to Eclipse, where I can drill down through an object graph with ease. I found the XCode debugger UI extremely difficult to use. Clicking on the stack to show code in an editor caused new windows to open, eventually resulting in dozens of windows open. In addition I found that watch expressions rarely worked for me. Profiler and Heap Analysis An area where Apple development tools excel is in profiling and heap analysis. These tools seemed mature and easy to use. With no prior experience with these specific tools I was able to gain a better understanding of my app within minutes, find and fix several memory leaks and improve performance. XCode Memory Leak Detection Android developers must use Android’s traceview application, which I found worked well but required significantly more effort to configure and operate. I was surprised to find that the source code must be changed in order to get the trace files required for analysis. I’m not sure if Android can provide heap dumps in hprof format. If it can then the awesome MAT tool could be used to analyze heap usage. According to this article Android can produce hprof heap data, though I haven’t tried it. App Store It goes without saying that the iPhone app store is excellent in that you can sell into many countries worldwide with a single setup. I was able to provide my Canadian bank account number, sign a few legal agreements and I was up and running. Getting an app into the store however is frustrating to say the least. Apple must approve every app before it is accepted into the store. Mine got rejected multiple times. Each time it was rejected I was given almost no information about why. When I emailed them to clarify the problem, I received what looked like a canned response indicating that I should refer to previous correspondence. If it weren’t so frustrating I would have found it funny. I highly recommend reading Brian Stormont’s Avoiding iPhone App Rejection from Apple and Dan Grigsby’s Part 2 follow-up. Of course once I started selling Hudson Helper I realized that Apple won’t send me any money unless the payout is greater than $250. This is true not only of the first payout, but every payout. Google market on the other hand requires a minimum of $1 for each payout. Both the iPhone app store and Google market take about %30 of your app selling price. $0.99 applications have to have high volume, or they’re simply not worth your time. The Google market by comparison to the Apple app store is terrible in that you can only sell into a handful of countries. You also can’t see or install apps that cost money on a developer phone. Actually you can, but not if the app has copy protection — which is almost every non-free app. On the other hand when you upload your app to the app store it’s available within minutes, so you don’t have to worry about an approval process. To set up a merchant account with Google market, I had to provide a US address and bank account number, since Google doesn’t support Canada. For me this was a pain, but not too bad since I live within a few kilometers of the US border. I rode my bike down to the US and opened an account with Horizon bank. The bank required a passport and driver’s license, so no problem there. Why Google doesn’t support more countries I don’t know. At the very least Google market should accept alternate payment methods for countries that are not supported by Google checkout. Summary Android’s platform and developer tools are excellent. Leveraging Java and the Eclipse IDE are major winning factors for Android. Apple’s developer tools are shockingly bad by comparison. The Objective-C language and platform APIs are cumbersome and poorly organized. Overall when developing for the iPhone I felt like I was back in 1993. These factors combined in my estimation make application development about three times more expensive when developing for iPhone. The only area where Apple’s developer tools excelled was in profiling and heap analysis. Apple’s app store from a user’s standpoint and from a worldwide coverage standpoint are excellent. In this area Google market for Android is weak. Development for iPhone may improve as tools such as iphonical (MDD for iPhone) and objectiveclipse (Eclipse plug-in for Objective-C) emerge. We may see a shake-up in the mobile market, with at least 18 new Android handsets being released this year. Until that happens, iPhone will remain a market leader and developers will have to put up with XCode and Objective-C. For me, my love is with Android. Sure, the iPhone is great — but can you install a new Linux kernel? From http://greensopinion.blogspot.com/
July 6, 2009
by David Green
· 93,102 Views
article thumbnail
JMS Over HTTP Using OpenMQ (Sun Java System Message Queue and HTTP Tunneling)
You may have already faced a situation where you need to have messaging capabilities in your application while your client application runs in an environment, which you have no control over its network configuration and restrictions. Such situation lead to the fact that you can not use JMS communication over designated ports like 7676 and so. You may simply put JMS away and follow another protocol or even plain HTTP communication to address your architecture and design requirement, but we can not easily put pure JMS API capabilities away as we may need durable subscription over a proven and already well tested and established design and architecture. Different JMS implementation providers provide different type capabilities to address such a requirement. ActiveMQ provide HTTP and HTTPS transport for JMS API and described it here. OpenMQ provide different transport protocol and access channels to access OpenMQ functionalities from different prgramming . One of the access channles which involve HTTP is named Universal Message Service (UMS) which provide a simple REST interaction template to place messages and comsume them from any programming language and device which can interact with a network server. UMS has some limitations which is simply understandable based on the RESTful nature of UMS. For current version of OpenMQ, it only supports Message Queues as destinations so there is no publish-subscribe functionality available. Another capability which involve HTTP is JMS over HTTP or simply JMS HTTP tunneling. OpenMQ JMS implementation supports HTTP/s as transport protocol if we configure the message broker properly. Well I said the JMS implementation support HTTP/S as a transport protocol which means we as user of the JMS API see almost no difference in the way that we use the JMS API. We can use publish-subscribe, point to point, durable subscription, transaction and whatever provided in the JMS API. First, lets overview the OpenMQ installation and configuration then we will take a look at an example to see what changes between using JMS API and JMS API over HTTP transport. Installation process is as follow: OpenMQ project provides a Java EE web application which interact with OpenMQ broker from one side and Sun JMS implementation on the other side. Interaction of this application with the client and MQ broker is highly customizable in different aspects like Broker port number, client poll inrval, Broker address and so on. Download OpenMQ from https://mq.dev.java.net/ it should be a zip which is different for each platform. Install the MQ by unzipping the above file and running ./installer or installer.bat or so. After the installation completed, go to install_folder/var/mq/instances/imqbroker/props and open the config.properties in a text editor like notepad or emeditor or gedit. Add the following line to the end of the above file: imq.service.activelist=jms,admin,httpjms Now goto install_folder/mq/lib/ and pick the imqhttp.war file. deploy the file into your Servlet container or application server (I went with GlassFish). After you deployed the file start the application server or Servlet container Now it is time to start the MQ broker: launch a terminal or cmd console and goto install_folder/mq/bin now execute ./imqbrokerd -port 7979 (it maybe like imqbrokerd.bat -port 7979 for Windows ) This command will start the MQ broker and keep it listening on port 7979 for incoming connection To test the overall operations: Open a browser and tray to surf http://127.0.0.1:8080/imqhttp/tunnel or whatever URL which points to the newly deployed application . If you saw "HTTP tunneling Servlet ready." as the first line in the response page then we are ready for last step. Now let's see how we can publish some messages, this sample code assume that we have configured the message broker and assumes that we have the following two JAR files in the classpath. These JAR files are available in install_folder/mq/lib/ imq.jar jms.jar Now the Publisher code: public class Publisher { public void publish(String messageContent) { try { String addressList = "http://127.0.0.1:8080/imqhttp/tunnel"; com.sun.messaging.TopicConnectionFactory topicConnectionFactory = new com.sun.messaging.TopicConnectionFactory(); topicConnectionFactory.setProperty(com.sun.messaging.ConnectionConfiguration.imqAddressList, addressList); javax.jms.Topic top; javax.jms.Connection con = topicConnectionFactory.createTopicConnection("admin", "admin"); javax.jms.Session session = con.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE); top = session.createTopic("DIRECT_TOPIC"); MessageProducer prod = session.createProducer(top); Message textMessage = session.createTextMessage(messageContent); prod.send(textMessage); prod.close(); session.close(); con.close(); } catch (JMSException ex) { ex.printStackTrace(); } } public static void main(String args[]) { Publisher p = new Publisher(); for (int i = 1; i < 10; i++) { p.publish("Sample Text Message Content: " + i); } } } As you can see the only difference is the connection URL which uses http instead of mq and point to a Servlet container address instead of pointing to the Broker listening address. The subscriber sample code follow a similar pattern. Here I write a sample durable subscriber so you can see that we can use durable subscribtion over HTTP. But you should note that HTTP transport uses polling and continuesly open communication channel which can introduce some overload on the server. class SimpleListener implements MessageListener { public void onMessage(Message msg) { System.out.println("On Message Called"); if (msg instanceof TextMessage) { try { System.out.print(((TextMessage) msg).getText()); } catch (JMSException ex) { ex.printStackTrace(); } } } } public class Subscriber { /** * @param args the command line arguments */ public void subscribe(String clientID, String susbscritpionID) { try { // TODO code application logic here String addressList = "http://127.0.0.1:8080/imqhttp/tunnel"; com.sun.messaging.TopicConnectionFactory topicConnectionFactory = new com.sun.messaging.TopicConnectionFactory(); topicConnectionFactory.setProperty(com.sun.messaging.ConnectionConfiguration.imqAddressList, addressList); javax.jms.Topic top; javax.jms.Connection con = topicConnectionFactory.createTopicConnection("admin", "admin"); con.setClientID(clientID); javax.jms.Session session = con.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE); top = session.createTopic("DIRECT_TOPIC"); TopicSubscriber topicSubscriber = session.createDurableSubscriber(top, susbscritpionID); topicSubscriber.setMessageListener(new SimpleListener()); con.start(); } catch (JMSException ex) { ex.printStackTrace(); } } public static void main(String args[]) { Subscriber sub = new Subscriber(); sub.subscribe("C19", "C1_011"); } } Now how you can test the entire example and monitor the MQ? it is very simple by utilizing the provided tools. Do the following steps to test the overall durable subscription system: Run a subscriber Run another subscriber with a different client ID Run a publisher once or twice Kill the second subscriber Run a publisher once Run the subscriber and you can see that the subscriber will fetch all messages which arrived after it shut down-ed. Note that we can not have two separate client with same client ID running because the broker will not be able to distinguish which client it should send the messages. You can monitor the queue and the broker using: ./imqadmin which can be found in install_folder/mq/bin this software shows how many durable subscribers are around and how many messages are pending for each subscriber and so on. You can monitor the Queue in real-time mode using the following command which can be executed in install_folder/mq/bin ./imqcmd -b 127.0.0.1:7979 metrics dst -t t -n DIRECT_TOPIC The command will ask for username and password, give admin/admin for it The sample code for this entry can be found Here. The sample code is a NetBeans project with the publisher and the subscriber source code. A complete documentation of OpenMQ is available at its documentation centre. You can see how you can change different port numbers or configure different properties of the Broker and HTTP tunneling web application communication.
June 22, 2009
by Masoud Kalali
· 34,693 Views
article thumbnail
Hibernate Performance Tuning
Hibernate is a powerful, high performance object/relational persistence and query service. Hibernate lets you develop persistent classes following object-oriented idiom - including association, inheritance, polymorphism, composition, and collections. Hibernate allows you to express queries in its own portable SQL extension (HQL), as well as in native SQL, or with an object-oriented Criteria and Example API. Quintessential to using any ORM framework like hibernate is to know how to leverage the various performance tuning methods supported by the framework. In this volume Wings Jiang discusses three performance tuning strategies for hibernate: SQL Optimization Session Management Data Caching SQL Optimization When using Hibernate in your application, you already have been coding HQL (Hibernate Query Language) somewhere. For example, “from User user where user.name = ‘John’”. If issuing your SQL statement like this, Hibernate cannot use the SQL cache implemented by database because name of the user, in most scenarios, is extremely distinct. On the contrary, while using placeholder to achieve this, like “from User user where user.name =?” will be cached by the Database to fulfill the performance improvement. You can also set some Hibernate properties to improve performance, such as setting the number of records retrieved while fetching records via configuring property hibernate.jdbc.fetch_size, setting the batch size when committing the batch processing via configuring property hibernate.jdbc.batch_size and switching off the SQL output via setting property hibernate.show_sql to false in product environments. In addition, the performance tuning of your target Database is also significant, like SQL clauses tuning, reasonable indexes, delicate table structures, data partitions etc. Session Management Undoubtedly, Session is the pith of Hibernate. It manages the Database related attributes, such as JDBC connections, data entities’ states. Managing the Session efficiently is the key to getting high performance in enterprise applications. One of the many commonly used and equally elegant approaches to session management in hibernate is to use ThreadLocal. Threadlocal will create a local copy of session for every thread. Thus synchronization problems are averted, when objects are put in the Threadlocal, . To understand how ThreadLocal variables are used in Java, refer to Sun Java Documentation at http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ThreadLocal.html Data Caching Before accomplishing any data caching, it is essential to set the property hibernate.cache.user_query_cache = true. There are three kinds of commonly used Caching Strategies in Hibernate: Using cache based on Session level (aka Transaction layer level cache). This is also called first-level cache. Using cache based on SessionFactory level (Application layer level cache). This is also called second-level cache. Using cluster cache which is employed in distributed application (in different JVMs). In fact, some techniques, like loading data by id, lazy initialization which betokens loading appropriate data in proper time rather than obtaining a titanic number of useless records, which are fairly useless in the subsequent operations are consummated via data caching. First Level Cache (aka Transaction layer level cache) Fetching an object from database always has a cost associated with it. This can be offset by storing the entities in hibernate session. Next time the entities are required, they are fetched from the session, rather than fetching from the database. To clear an object from the session use: session.evict(object). To clear all the objects from the session use session.clear(). Second Level Cache (aka Application layer level cache) In this approach, if an object is not found in session, it is searched for in the session factory before querying the database for the object. If an object is indeed fetched from database, the selected data should be put in session cache. This would improve the performance when the object is required next time. To remove an entity from session factory use the various overloaded implementations of evict() method of SessionFactory. In fact, Hibernate lets you tailor your own caching implementation by specifying the name of a class that implements org.hibernate.cache.CacheProvider using the property hibernate.cache.provider_class. But it is recommended to employ a few built-in integrations with open source cache providers (listed below). Cache Type Cluster Safe Query Cache Supported Hashtable Memory NO YES EHCache Memory, Disk NO YES OSCache Memory, Disk NO YES SwarmCache Clustered YES (clustered invalidation) NO JBoss TreeCache Clustered YES (replication) YES Terracota Clustered YES YES In order to use second level caching, developers have to append some configurations in hibernate.cfg.xml (for example, using EHCache here). net.sf.ehcache.hibernate.Provider In addition, developers also need to create a cache specific configuration file (Example: ehcache.xml for EHCache). (1) diskStore : Sets the path to the directory where cache .data files are created. The following properties are translated: a.user.home - User's home directory b.user.dir - User's current working directory c.java.io.tmpdir (Default temp file path) maxElementsInMemory : Sets the maximum number of objects that will be created in memory. eternal : Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. timeToIdleSeconds : Sets the time to idle for an element before it expires. Is only used if the element is not eternal. Idle time is now - last accessed time. timeToLiveSeconds : Sets the time to live for an element before it expires. Is only used if the element is not eternal. TTL is now - creation time overflowToDisk : Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit. Finally the cache concurrency strategy has to be specified in mapping files. For example, the following code fragment shows how to configure your cache strategy. … … Cache Concurrency Strategies There are four kinds of built-in cache concurrency strategies provided by Hibernate. Chosing a right concurrency strategy for your hibernate implementation is the key to cache performance optimization. Besides to ensure data consistency and transaction integrity it is indispensable to master these strategies. read-only If your application needs to read but never modify instances of a persistent class, a read-only cache may be used. This is the simplest and best performing strategy. It's even perfectly safe for use in a cluster. nonstrict-read-write If the application only occasionally needs to update data (For example, if it is extremely unlikely that two transactions would try to update the same item simultaneously) and strict transaction isolation is not required, a nonstrict-read-write cache might be appropriate. read-write If the application needs to update data, a read-write cache might be appropriate. This cache strategy should never be used if serializable transaction isolation level is required. transactional If the application seldom needs to update data and at the same time, application also needs to avoid “dirty read” and “repeatable read”, this kind of concurrency strategy can be employed. The transactional cache strategy provides support for fully transactional cache providers such as JBoss TreeCache. The following table lists cache concurrency strategy supported by various cache providers. Cache Read-only Nonstrict-read-write Read-write Transactional Hashtable YES YES YES N/A EHCache YES YES YES N/A OSCache YES YES YES N/A SwarmCache YES YES N/A N/A JBoss TreeCache YES N/A N/A YES Cluster Cache (in different JVMs) Hibernate also supports cluster caching in disparate JVMs. At present, both SwarmCache and JBoss TreeCache support cluster caching across multiple JVMs. In some situations, especially at the level of enterprise, certain application has to support the concurrency accessing of thousands of users, at that time, cluster cache can help you because the cluster can provide failover and load balancing which improve the performance of application. Points to Note When employing one of the four cache strategies above, pay close attention to the following situation: Data cached almost immutable If data you want to cache is almost constant, you can use data caching which can improve the performance of the application. On the contrary, if the caching data are quiet volatile, Hibernate have to maintain and update the caching over time which extremely leads to performance hit. Data sizes in reasonable range If the size of data you is caching is massive, Hibernate will occupy the most memories of system, which causes the long waiting time of the whole application. Low frequency of data updating If data you are caching needs to be modified frequently, Hibernate have to take an array of time to update and modify the data in caching, which impacts the performance of the application as well. High frequency of data querying If data you are caching is steady, which means that most of the operations are querying, searching, no updating and modifying, making the most use of caching will be affording huge performance improvement. None crucial data Because of existing some incongruities when keeping the data in caching, so if the data you are caching is fairly crucial, do not use caching. By contrast, if the data in caching is insignificant, just use it without any vacillation. Summary Actually, after employing SQL Optimization, Session Management, Data Caching, we will obtain great battalions of performance gains, which make applications achieve acceptable waiting time for the final customers. External Links for Further Study http://www.hibernate.org/hib_docs/reference/en/html/performance.html http://blogs.jboss.com/blog/acoliver/2006/01/23/Hibernate_EJB3_Tuning.txt About Author I am Wings Jiang from BCM China. I have mainly focused on J2EE technologies in recent years and worked in several projects involving Struts/Tapestry, Spring, Hibernate, WebLogic, Websphere, Oracle, DB2 etc. I have experience in design and code of several Java applications. Hibernate performance is one of the areas I pay close heed to in my current working.
June 10, 2009
by Ming Jiang
· 141,803 Views · 4 Likes
article thumbnail
Java Properties Without Getters and Setters
During the last Devoxx conference, Mark Reinhold, Sun's chief engineer for Java SE, gave a presentation on the latest directions for Java 7. (Hamlet D'Arcy's summary of Mark's presentation is available here.) One of the features that was discussed for possible inclusion in Java 7, but won't find its way into the final release, is first class properties for Java. First-class support for properties would have gone beyond the simple setter and getter methods of the JavaBeans specification, and provided a succinct and elegant way for defining properties for Java objects. Properties are already first-class elements of many modern languages, so this lack in Java 7 will be felt by many developers accustomed to other languages' property support. At the same time, Java developers can resort to a handful of other techniques in working with property-like Java attributes, and some of the possible techniques work even in Java 1.4. In the rest of this article, I will demonstrate one such technique use a simple aspect, with AspectJ, and some following some conventions. Motivation The idea for this solution arose while working with the OpenXava 3 framework. OpenXava defines a mechanism to develop Java Enterprise applications using Business Components. It's an alternative way to MVC: instead of organizing the code into Model, a View and a Controller, the code with OpenXava is organized around Invoice, Customer, Order, and similar business-centric objects. OpenXava initially used XML for defining components, but since version 3 the use of POJOs with Java 5 annotations also became available as the preferred way to define business components. When using the XML-based object definition, you may specify a component in the following manner: Using the annotation-based OpenXava 3, the same component would be defined as follows: @Entity public class Teacher { @Id @Column(length=5) @Required private String id; @Column(length=40) @Required private String name; @OneToMany(mappedBy="teacher") private Collection pupils; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Collection getPupils() { return pupils; } public void setPupils(Collection pupils) { this.pupils = pupils; } } This illustrates some of the verbosity with the Java definition: 37 lines against the 13 of XML version. The problem occurs because of the getters and setters. The boilerplate code adds noise and increases the size of the file without increasing the information to the programmer. Use Java and annotations as a definition language in OpenXava would welcome a more succinct and elegant syntax. A More Succinct Solution A better solution can be obtained by defining the business component in this way: @Entity public class Teacher { @Id @Column(length=5) @Required public String id; @Column(length=40) @Required public String name; @OneToMany(mappedBy="teacher") public Collection pupils; } This makes Java more beautiful, succinct and elegant... just as XML. With this, you have to use the following properties without getters and setters. That is, instead of: teacher.setName("M. Carmen"); String result = teacher.getName(); you write: teacher.name = "M. Carmen"; String result = teacher.name; In this case name is not a field, but a property. You can refine the access to this property, and even create pure calculated properties. For example, if you wanted a calculated property, you could define it in this way: @Entity public class Person { ... public String name; public String surname; transient public String fullName; // (1) protected String getFullName() { // (2) return name + " " + surname; } } In order to define a calculated property, you define a public field (1) and then a protected (or private, but not public) getter (2). This getter, getFullName() in this case, is for implementing the logic for the property fullName. Using this property is simple: Person p = new Person(); p.name = "M. Carmen"; p.surname = "Gimeno Alabau"; assertEquals("M. Carmen Gimeno Alabau", p.fullName); When p.fullName is used, the method getFullName() is executed for returning the value. You can see that fullName is a property, not a simple field. You can also refine access to writing and reading the properties. For example, you can define a property as following: public String address; protected String getAddress() { return address.toUpperCase(); } When address is used from outside the class the method getAddress() is used to obtain the result, but this method only returns the address with some refinement. As we use address field from inside getAddress() field address from inside of its class is used, and the getter is not called. Now you can use this property as follows: Person p = new Person(); p.address = "Av. Baron de Carcer"; assertEquals("AV. BARON DE CARCER", p.address); As well, you can define setters, even for vetoing the data to be set, as in the next example: public int age; protected void setAge(int age) { if (age > 200) { throw new IllegalArgumentException("Too old"); } this.age = age; } As in the case of the getter, if a setter method is present it will be executed to set the data, you can use this logic to set the data to the field or for any other logic you want. Now you can use this property in this way: Person p = new Person(); p.age = 33; assertEquals(p.age, 33); p.age = 250; // Here an IllegalArgumentException is thrown In summary: Properties behave from outside of the class as public fields. If no getter or setter for the field exists, a direct access for the field is performed. If a getter exists for the field, it will be executed when trying to read the field from outside. If a setter exists for the field, it will be executed when trying to write the field from outside. From inside the class, all references to the field are direct access, without calling getter or setter. This provides a simple and natural way to have properties in Java without unnecessary getters and setters. Implementation This simple mechanism is easy to implement using AspectJ and a simple aspect, and it will work even in Java 1.4. For this to work, you only need to have an aspect in your project: aspect PropertyAspect { pointcut getter() : get(public !final !static * *..model*.*.*) && !get(public !final !static * *..model*.*Key.*) && !within(PropertyAspect); pointcut setter() : set(public !final !static * *..model*.*.*) && !set(public !final !static * *..model*.*Key.*) && !within(PropertyAspect); Object around(Object target, Object source) : target(target) && this(source) && getter() { if (target == source) { return proceed(target, source); } try { String methodName = "get" + Strings.firstUpper( thisJoinPointStaticPart.getSignature().getName()); Method method = target.getClass(). getDeclaredMethod(methodName, null); method.setAccessible(true); return method.invoke(target, null); } catch (NoSuchMethodException ex) { return proceed(target, source); } catch (InvocationTargetException ex) { Throwable tex = ex.getTargetException(); if (tex instanceof RuntimeException) { throw (RuntimeException) tex; } else throw new RuntimeException( XavaResources.getString("getter_failed", thisJoinPointStaticPart. getSignature().getName(), target.getClass()), ex); } catch (Exception ex) { throw new RuntimeException( XavaResources.getString("getter_failed", thisJoinPointStaticPart.getSignature().getName(), target.getClass()), ex); } } void around(Object target, Object source, Object newValue) : target(target) && this(source) && args(newValue) && setter() { if (target == source) { proceed(target, source, newValue); return; } try { String methodName = "set" + Strings.firstUpper(thisJoinPointStaticPart.getSignature().getName()); Class fieldType = ((FieldSignature) thisJoinPointStaticPart.getSignature()).getFieldType( Method method = target.getClass(). getDeclaredMethod(methodName, new Class[] {fieldType}); method.setAccessible(true); method.invoke(target, new Object[] { newValue } ); } catch (NoSuchMethodException ex) { proceed(target, source, newValue); } catch (InvocationTargetException ex) { Throwable tex = ex.getTargetException(); if (tex instanceof RuntimeException) { throw (RuntimeException) tex; } else throw new RuntimeException( XavaResources.getString("setter_failed", thisJoinPointStaticPart.getSignature().getName(), target.getClass()), ex); } catch (Exception ex) { throw new RuntimeException( XavaResources.getString("setter_failed", thisJoinPointStaticPart.getSignature().getName(), target.getClass()), ex); } } } Having defined this aspect, you will need to compile your project using AspectJ. The aspect intercepts all access to public fields in the model package, then use introspection to call to the getter or setter method if they exists. Drawbacks Unfortunately, this approach has at least two important drawbacks: It does not work when you access to the properties using introspection. With JPA, at least using the Hibernate implementation, lazy initialization does not work. You may think that the introspection problem can be overcome with your own custom introspection code. But the man third party libraries, frameworks, and toolkits will not obey those rules. For example, if you are using a report generator that can generate a report from a collection of Java objects, the report generator may expect real public getters and setters in the objects. The JPA the specification for Java Persistence API states that: 2.0: "Instance variables must not be accessed by clients of the entity. The state of the entity is available to clients only through the entity methods i.e., accessor methods (getter/setter methods) or other business methods." JSR 317 : JavaTM Persistence API, Version 2.0 - Public Review Draft - Section 2.1 That is, portable JPA code should not rely on direct access to properties. Conclusion This article presents a very simple way to work with properties in Java, even though the language doesn't support properties. If the AspectJ implementation is not practical, you can find other implementations of this idea using asm or cglib. References OpenXava - http://www.openxava.org/ AspectJ - http://www.eclipse.org/aspectj/
May 30, 2009
by Javier Paniza
· 79,620 Views · 1 Like
article thumbnail
The Best Kept Secret in the JDK: VisualVM
It's amazing the things that are right in front of you that you don't realise. VisualVM is probably the best example of this in the Java community.
May 28, 2009
by James Sugrue
· 226,694 Views · 7 Likes
article thumbnail
JavaFX: Using Patterns & Clean Code
We are seeing quite a number of exciting JavaFX demos around, demonstrating the pretty features of the language and the capability of easily integrating cool graphics. But, as a software designer, I can't prevent myself from seeing that in most examples we see bloated code - no good separation of concerns and poor applications of the MVC pattern. This is reasonable, as JavaFX was a new language and people needed first to be taught about the syntax and features; but now that - I presume - many of us have been introduced with the new language, it's high time we started worrying about good practices, as well as writing self-commenting code. Let's remember that good practices and good design are always more important than the language! So, let's introduce a very simple project - a Contact List whose specifications are: We have a list of "contacts", where each item is name, last name, email, phone, etc... The UI shows a list of contacts, that can be filtered by a text field; if you enter a value in it, only the contacts whose name starts with the entered text are shown. Selections are applied as you type. Selecting an item in the list of contacts, the details are shown in a form, where you can edit them. At any selection change, the form is animated (a rotation and a blur effect). You can get the code from: svn co -r 37 https://kenai.com/svn/javafxstuff~svn/trunk/ContactList/src/ContactList The model Let's first have a quick look at the model classes. First a simple value object representing a piece of data: package it.tidalwave.javafxstuff.contactlist.model; public class Contact { public var id: String; public var firstName: String; public var lastName: String; public var phone: String; public var email: String; public var photo: String; override function toString() { return "\{id: {id}, value: {firstName} {lastName}, phone: {phone}, email: {email}" } } Then a small service which provides a bunch of data: package it.tidalwave.javafxstuff.contactlist.model; public abstract class ContactRegistry { public abstract function items() : Contact[]; } In the demo code, you'll find a mock implementation with some wired values; in a real case this could be a Business Delegate encapsulating code for retrieving data remotely. So far, so good - it's pretty normal to keep these things separated from the UI. The Controllers We're not going to see a classic Controller here; actually, we're slightly departing from the "pure" MVC. The code I'm showing you is more a "Presentation Model", a pattern described by Martin Fowler as: The essence of a Presentation Model is of a fully self-contained class that represents all the data and behavior of the UI window, but without any of the controls used to render that UI on the screen. A view then simply projects the state of the presentation model onto the glass. This class is basically an hybrid between a classic model and a controller. It is also a façade between the view and the domain model. package it.tidalwave.javafxstuff.contactlist.model; import it.tidalwave.javafxstuff.contactlist.model.ContactRegistry; import it.tidalwave.javafxstuff.contactlist.model.ContactRegistryMock; public class PresentationModel { public var searchText : String; public var selectedIndex : Integer; // The Business Delegate def contactRegistry = ContactRegistryMock{} as ContactRegistry; def allContacts = bind contactRegistry.items(); // The contacts filtered according the contents of the search field public-read def contacts = bind allContacts[contact | "{contact.firstName} {contact.lastName}".startsWith(searchText)]; // The selected contact; the code also triggers a notification at each change public-read def selectedContact = bind contacts[selectedIndex] on replace previousContact { onSelectedContactChange(); }; // Notifies a change in the current Contact selection public-init var onSelectedContactChange = function() { } } Note the extreme compactness brought by functional programming. There's almost no imperative programming as everything is achieved by properly using the binding feature. The only imperative part is the 'onSelectedContactChange' function, which is just a listener to notify selection changes to some external code - it will be used only for triggering the animation. BTW, I'd like to remove it from here, but I wasn't able to. Maybe it's a JavaFX thing that I've not understood yet, but I'm keeping it for another post. Now, everything about the animation goes encapsulated in a specific class, which only exposes two properties controlling the animation: the effect and the rotation angle. A single play() function is provided to start the animation. package it.tidalwave.javafxstuff.contactlist.view; import javafx.animation.Interpolator; import javafx.animation.Timeline; import javafx.scene.effect.GaussianBlur; public class AnimationController { public-read var rotation = 0; public-read def effect = GaussianBlur{} def timeline = Timeline { repeatCount: 1 keyFrames: [ at(0s) { effect.radius => 20; rotation => 45 } at(300ms) { effect.radius => 0 tween Interpolator.EASEBOTH; rotation => 0 tween Interpolator.EASEBOTH } ] } public function play() { timeline.playFromStart(); } } The Views Now, a UI component. The way we design it largely depends on the process, as a graphic designer could be involved. In any case, I think that the whole UI should not be implemented in a single, bloated class; rather relevant pieces should be split apart. For instance, a CustomNode can model the "form" that renders the contact details (in the code below I've omitted all the attributes related to rendering): package it.tidalwave.javafxstuff.contactlist.view; import javafx.scene.CustomNode; import javafx.scene.Group; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.Node; import javafx.ext.swing.SwingLabel; import javafx.ext.swing.SwingTextField; import it.tidalwave.javafxstuff.contactlist.model.Contact; public class ContactView extends CustomNode { public var contact : Contact; public override function create() : Node { return Group { content: [ VBox { content: [ SwingLabel { text: bind "{contact.firstName} {contact.lastName}" } HBox { content: [ SwingLabel { text: "First name: " } SwingTextField { text: bind contact.firstName } ] } HBox { content: [ SwingLabel { text: "Last name: " } SwingTextField { text: bind contact.lastName } ] } HBox { content: [ SwingLabel { text: "Email: " } SwingTextField { text: bind contact.email } ] } HBox { content: [ SwingLabel { text: "Phone: " } SwingTextField { text: bind contact.phone } ] } ] } ] }; } } As you can see, we have only layout and data binding here, the only things a view should do. Putting all together Now the last piece of code, the Main, which builds up the application (again, I've omitted all attributes only related to rendering): package it.tidalwave.javafxstuff.contactlist.view; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.Scene; import javafx.stage.Stage; import javafx.ext.swing.SwingLabel; import javafx.ext.swing.SwingList; import javafx.ext.swing.SwingListItem; import javafx.ext.swing.SwingTextField; import it.tidalwave.javafxstuff.contactlist.controller.PresentationModel; Stage { def animationController = AnimationController{}; def presentationModel = PresentationModel { onSelectedContactChange : function() { animationController.play(); } }; scene: Scene { content: VBox { content: [ HBox { content: SwingLabel { text: "Contact List" } } HBox { content: [ SwingLabel { text: "Search: " } SwingTextField { text: bind presentationModel.searchText with inverse } ] } HBox { content: [ SwingList { items: bind for (contact in presentationModel.contacts) { SwingListItem { text:"{contact.firstName} {contact.lastName}" } } selectedIndex: bind presentationModel.selectedIndex with inverse } ContactView { contact: bind presentationModel.selectedContact effect: bind animationController.effect rotate: bind animationController.rotation } ] } ] } } } As in the previous code snippets, I think the listing can be easily read and understood. Basically, we are glueing all the pieces together and binding the relevant models. In the end, each class in this small project does a simple, cohese thing: representing data, encapsulating the presentation logic, controlling the animation, rendering the views. Dependencies are reduced to the minimum and they have the correct direction: views depend on the models (and not the opposite) and the AnimationController; the AnimationController is independent. You could replace the view components without affecting the rest of the classes, as well as removing or adding other animations by properly using different AnimationControllers. This good separation of roles and responsibilities is the good way to apply OO. There is a detail which is worth discussing. Note the two bind ... with inverse. They implement the so-called "bidirectional binding" where not only a change in the model (e.g. PresentationModel.selectedIndex) is reflected to attributes in the UI (e.g. SwingList.selectedIndex), but also the opposite happens. Indeed, the reverse binding is more important in our example, because it implements the controller responsibility (it captures user's gestures from the view and changes the model); the direct binding from the PresentationModel to SwingList, instead, is useless, as in our case the PresentationModel is never the originator of a change. So, why not using a simple, direct binding in PresentationModel towards SwingList? Such as: public class PresentationModel { var list : SwingList; public def selectedIndex = bind list.selectedIndex; ... } Because this would introduce a dependency from the model/controller to the view, which is plain wrong. Here, bind ... with inverse not only works as a shortcut for writing less code (that is, explicitly declaring a binding and its inverse), but it's also an essential feature for a better design. As far as I know - but I could be wrong - for example in ActionScript (Adobe Flex language) there's no bidirectional binding (you need to put binding keywords at both ends of the association), thus introducing unneeded or circular dependencies. I believe this is true at least at code level (as far as I understand, there are different ways to do binding in ActionScript).
May 12, 2009
by Fabrizio Giudici
· 45,986 Views
article thumbnail
Top 10 Open Source Projects for .NET Developers
There are many useful, practically essential, open source solutions available to .NET developers. This is a list of the ones that have been the most useful in my experience. Agree? Disagree? Leave a comment with your own suggestions. NHibernate - NHibernate is a mature, open source object-relational mapper for the .NET framework. It's actively developed, fully featured and used in thousands of successful projects. http://nhforge.org/Default.aspx NUnit - NUnit is a unit-testing framework for all .Net languages. Initially ported from JUnit, the current production release, version 2.4, is the fifth major release of this xUnit based unit testing tool for Microsoft .NET. It is written entirely in C# and has been completely redesigned to take advantage of many .NET language features, for example custom attributes and other reflection related capabilities. NUnit brings xUnit to all .NET languages. http://www.nunit.org/index.php jQuery - jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript. http://jquery.com/ Rhino.Mocks - A dynamic mock object framework for the .Net platform. It's purpose is to ease testing by allowing the developer to create mock implementations of custom objects and verify the interactions using unit testing. http://ayende.com/projects/rhino-mocks.aspx MVC Contrib - This is the contrib project for the ASP.NET MVC framework. This project adds additional functionality on top of the MVC Framework. These enhancements can increase your productivity using the MVC Framework. It is written in C#. Founded by Eric Hexter and Jeffrey Palermo. http://www.codeplex.com/MVCContrib CruiseControl.NET - CruiseControl.NET is an Automated Continuous Integration server, implemented using the Microsoft .NET Framework. http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET S#arp Architecture - Pronounced "Sharp Architecture," this is a solid architectural foundation for rapidly building maintainable web applications leveraging the ASP.NET MVC framework with NHibernate. The primary advantage to be sought in using any architectural framework is to decrease the code one has to write while increasing the quality of the end product. A framework should enable developers to spend little time on infrastructure details while allowing them to focus their attentions on the domain and user experience. http://code.google.com/p/sharp-architecture/ Spark View Engine - Spark is a view engine for Asp.Net Mvc and Castle Project MonoRail frameworks. The idea is to allow the html to dominate the flow and the code to fit seamlessly. http://sparkviewengine.com/ TortoiseSVN - A Subversion client, implemented as a windows shell extension. TortoiseSVN is a really easy to use Revision control / version control / source control software for Windows. Since it's not an integration for a specific IDE you can use it with whatever development tools you like. TortoiseSVN is free to use. You don't need to get a loan or pay a full years salary to use it. http://tortoisesvn.tigris.org/ Castle Windsor - Castle Project offers two Inversion of Control Containers. The MicroKernel and the Windsor Container. Castle Windsor aggregates the MicroKernel and exposes a powerful configuration support. It is suitable for common enterprise application needs. It is able to register facilities and components based on the configuration and adds support for interceptors. http://www.castleproject.org/container/index.html
May 4, 2009
by Alvin Ashcraft
· 88,220 Views
article thumbnail
Why Java (and Other Languages) Don't Need Operator Overloading
If you knew that the language that you are reading supports it, you are just going to extend this mental path to operations that involve overridable operators.
April 13, 2009
by Cedric Beust
· 86,028 Views · 1 Like
  • Previous
  • ...
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573
  • 574
  • 575
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×