Welcome!

ColdFusion Authors: Pat Romanski, Liz McMillan, Maureen O'Gara, Greg Ness, Andreas Grabner

Related Topics: ColdFusion

ColdFusion: Article

ColdFusion MX/J2EE Hybrid Applications

ColdFusion MX/J2EE Hybrid Applications

Since the release of ColdFusion MX, the ColdFusion community has been rumbling about the possibilities made available by CFMX's powerful Java 2 Enterprise Edition (J2EE) underpinnings; using servlets, JavaServer Pages (JSP), JavaBeans, and Enterprise JavaBean (EJB) components are the most notable examples.

Out of this discussion has arisen the concept of ColdFusion/J2EE hybrid applications. As an ideal, CFMX/J2EE hybrids offer the rapid development and robust high-level services of CFMX, while integrating the deeper transactional and low-level programming power of Java.

With all of the possibilities for architecting and developing these hybrid applications, it seems to me that it's time for the ColdFusion development community to seriously discuss what some of the best practices might be when developing these hybrid applications. Surely there are infinite possibilities for integrating CFMX with J2EE, but which of these are viable and truly offer the best that both frameworks have to offer?

This is the question I have been asking myself again and again over the past few months while I collaborated on a book about this topic (Reality ColdFusion: J2EE Integration), developed applications (including the Lindex component using Apache Lucene for the Macromedia Developer's Resource Kit 3), and did a case study for Macromedia's DevNet site (www.macromedia.com/devnet/mx/coldfusion/ j2ee/articles/hybrid.html) on hybrid applications. In short, I've been living a hybrid life. This article is not only to share what I've learned, but also to contribute to and further an ongoing discussion on best practices for CFMX/J2EE hybrid applications.

Note: in order to best focus on the subject at hand, I have foregone providing background on what the two environments, CFMX and J2EE, are. If you are looking for more background information on this subject, I suggest the following resources:

  • Chapter 32 of the CFMX manual, "Developing ColdFusion MX Applications with CFML," online at http://livedocs.macromedia.com/cfmxdocs/ Developing_ColdFusion_MX_Applications_with_CFML/Java.jsp
  • Ben Forta's online presentation at Macromedia DevNet (www.macromedia.com/software/coldfusion/ j2ee/special/presentations/tech_intro/)
  • Ben Forta's CFDJ column in Volume 5, issue 3, "ColdFusion & Java: More than just the sum of their parts"
  • Reality ColdFusion: J2EE Integration, Forta, Falkman, et al (Macromedia Press)

    ColdFusion MX and J2EE: A Good Match
    What I've realized most in this process is that these two technologies really complement one another well. ColdFusion provides high-level services and an intuitive and rapid development framework, while J2EE provides low-level application programming interfaces (APIs) and powerful development objects. The most important thing to understand for anyone looking at developing hybrid applications is what each environment does well. Table 1 shows the key strengths and differences between both environments.

     

    At the core, CFMX brings rapid development to J2EE, something it was clearly lacking before. Developers can learn and become proficient in using CFML in significantly less time than Java, which requires understanding object-oriented programming concepts, strict data types, and a vast library of programming constructs. At the same time, because of its object-oriented nature and vast library collection, Java offers a considerable amount of control for those who know how to use it.

    In addition, the J2EE framework contains a number of programming constructs - such as EJBs and messaging services - that simply can't be emulated using ColdFusion alone. The best part of these differences is that there is no reason to choose one or the other anymore, just when to use which. This leads us to the heart of the matter: the best practices.

    The 10 Best Practices

    Best Practice #1:
    Use only what you need

    There's no reason to add complexity - ever. Introducing a second programming environment when you really need only one is nonsense. If you are building a CFMX application, don't use Java if you don't need to. The Java language is not as accessible as CFML - you'll add hours of learning, planning, and coding into your development process. Understand why you should use it first. With J2EE-only applications, you can likely gain a significant amount of time by using CFMX, even with the learning curve. However, if using CFMX means rewriting a significant amount of JSP/servlet code you may want to reconsider.

    Best Practice #2:
    Use what you already have

    Okay, this is another "no-duh" best practice, but I wouldn't feel right if I didn't mention it. If you have a CFML template that's handling a core, complex piece of business logic, don't recode it into an EJB or something else unless you have a compelling reason to do so. It needs to be distributed? Make it into a ColdFusion Component (CFC) and deploy it as a Web service. The same goes even more so for existing servlets and Java classes. It is relatively easy to integrate these items from within CFML. See the ColdFusion manual reference above for more information.

    In fact, capitalizing on existing code is a central argument for hybrid applications - use the Java code you have already developed, but build around it in CFMX (and in half the time it would take to do so in Java). In addition, this point should include capitalizing on open-source (or closed-source, for that matter) code in both environments. The ColdFusion community has a number of good resources for CF tags and user-defined functions, and the Java community has a huge open-source and third-party product community - use this prebuilt, pretested code whenever possible.

    Best Practice #3:
    Use CFMX for prototyping

    ColdFusion, because of its rapid development capabilities, makes an ideal prototyping solution. You can easily plug in a Microsoft Access (or mySQL) database, some CFQUERY and CFOUTPUT tags, and bam! (sorry Emeril...) you're up and running with a pretty deep prototype. You can then capitalize on your prototype code by tightening it up, adding error handling, and maybe converting the back-end processing into EJBs or other Java components. This is especially useful if you use Best Practice #4 in your conversion process.

    Best Practice #4:
    Use the CFC Façade pattern

    If I had to pick a best best practice, this would be it. CFCs allow CFMX developers to create their own components containing functions. These functions are then called on from within any CFML template, and can even be exposed as Web services. CFCs are perfect for calling on Java classes of any kind. Let's say you have an EJB that calculates sales tax for in-state orders. The taxBean EJB has a method called getTaxOwed() that you pass the total sales amount to. In a hybrid application, you would create a CFC called eCommerce.cfc or something like that. Inside of this CFC, you would create a function called getTaxOwed() (sound familiar?). This is simply an abstraction of the Java code. Then you can use CFINVOKE or CFSCRIPT to call on the getTaxOwed() CF function.

    This layer of abstraction makes irrelevant how the eCommerce.cfc works internally, thus allowing the getTaxOwed() CF function to call on an EJB or some other type of Java class, or even perform the logic itself. Using this pattern is great for prototyping - simply return dummy data in the prototype, and then when you plug it in for real, only the CFC needs to be changed. This is based on a well-established J2EE pattern called the Session Façade, whereby a session bean (EJB) is used to abstract logic of other EJB components. Figure 1 shows the CFC Façade pattern.

     

    Best Practice #5:
    Use the M-V-C pattern, with CFMX handling the V and usually the C

    M-V-C stands for Model-View-Controller. In this architecture, you have three primary sections of an application: the Model is the data model and includes data storage and logic processing; the View handles the user interface (UI); and the Controller handles the request and response (input/output) of the application. If you do not have existing servlets or JSP pages handling the UI and request/response processing (see Best Practice #2 above), let ColdFusion handle this.

    Between the Application.cfm, OnRequestEnd.cfm, CFMX's built-in security, and other services, as well as other frameworks (such as Fusebox and variations thereof), CFMX can effectively control an application, and output the UI - whether the UI is HTML, Flash, or XML. It is in this capacity that CFMX really shines. Developing the View/Controller aspects of an application in CFML will take so much less time than developing servlets and JSP pages that your job might become a part-time position, or you at least will have time (finally!) to get up to date on the water-cooler gossip.

    Best Practice #6: Use J2EE event listeners
    Of all the J2EE constructs at your disposal in CFMX, the event listener is one of the most unique. Listeners can "listen" to the application server for certain events to happen - such as sessions being destroyed and initiated - and then execute a block of code. There is nothing like this in CF, and it's something that many applications can gain from. For example, by listening to session destroys, a developer could program a process that saves abandoned shopping cart information to a database. Listeners can be turned on and off using the application server's deployment descriptor - an XML file - thus allowing for easy implementation without having to mess around with code and multiple if statements.

    Best Practice #7: Understand EJBs
    Before I go on touting the virtues of EJBs (see my CFDJ article, "Beefing up Your Applications with EJBs," Volume 4, issue 8 for more information), I should mention that some still debate whether EJBs are really necessary. That said, EJBs are deployable components, meaning that components reside in a container much like CFML templates and servlets/JSPs do. This container can enable beans to be called on by remote applications, and can allow beans to be clustered in their own array of servers and more.

    There are four types of beans: entity beans that handle interactions with datasources; message beans that handle messaging services; stateful session beans that store session data; and stateless session beans that handle business logic processing. All of these have a unique purpose. Because EJBs can be distributed across an enterprise, they can be an integral part of applications that are called on by other Java applications - be they desktop, applets, J2EE, or CFMX. They are also easy to deploy as Web services and to call on from .NET or other types of applications.

    Best Practice #8: The best J2EE elements to use (in my opinion)
    These are EJBs, JavaBean components, Java classes, event listeners, and maybe servlet filters (but only for server-wide processing directives). All of these components bring something to ColdFusion applications. In the case of JavaBean components and Java classes, they are especially useful when they encapsulate programming that requires low-level processing. I have already discussed the strength of EJBs and listeners. Servlet filters (for more information, see Charlie Arehart's article, "Fun with Filters," in CFDJ, Volume 5, issue 2) work much like the CFMX framework's Application.cfm and OnRequestEnd.cfm templates, processing code before or after a template (or servlet) is called on.

    Deciding whether to use the CFMX framework or servlet filters is a matter of choice, remembering that servlet filters are controlled (like event listeners) in the deployment descriptor, so they can be easily turned on/off and are especially handy when they provide processing for multiple applications - something that can't be done with the CFMX framework.

    Best Practice #9: Some J2EE elements are best used only if they already exist
    Specifically, these are controller or view servlets, JSP custom tags and JSP pages, and single-application or template servlet filters. Instead of servlets, use CFML templates. Of course some things are still best handled with servlets (note that Flash Remoting is servlet-based), but unless there is a specific reason to use servlets, CFML templates are way faster to build and still end up as compiled Java bytecode just like servlets. JSP tags can be extremely useful - there are numerous libraries available to handle everything from database calls to internationalization to Web services, but in most cases you shouldn't need to develop these specifically for an application. (See Charlie Arehart's article, "Using JSP Custom Tags in CFMX: What, Why, and How," in CFDJ Vol. 4, issue 5 for more information.)

    UDFs and ColdFusion custom tags are quicker to build. If you need low-level processing, Java classes are probably a better way to handle this. (For more on integrating Java classes in CFMX, see that CFMX manual reference as well as Guy Rish's eight-part series, "A Cold Cup o' Joe," starting in CFDJ Vol. 3, issue 1 and ending in Vol. 4, issue 8. While it discussed integration in CF 4.5 and 5, many of the same concepts for integrating with Java classes using CFOBJECT apply.)

    Finally, servlet filters, though handy, really don't offer much beyond what Application.cfm and OnRequestEnd.cfm do. If you need to process logic for only certain pages or folders, do a <cfif> check on the CGI.Script_Name variable; of course the exception is server-wide processing.

    Best Practice #10:
    Don't use JSP, Struts, Velocity, or other J2EE RAD "frameworks"

    I can hear my inbox already filling over this one. Any developer who has ever used both JSP and CFML will understand why eliminating JSP in its entirety is a good thing. Performing loops, controlling flow, and other programming logic either require external custom tags (which is an added pain compared to CFML) or scripting elements that make the code confusing and don't offer a clear separation of presentation and programming.

    Only use JSPs if they already exist and you won't need to modify them significantly to work with your application. Having used both, I have found it is often faster to rebuild in ColdFusion (using the existing JSP page as a starting point) than to make the modifications to the original JSP pages and maybe their controller servlets. For example, Java developers will often put queries in the controller servlet, then output in the JSP page.

    So if you want to add a field to the output, you need to edit (and recompile) the servlet to change the query (usually in a Java IDE), and edit the JSP (usually in an HTML editor) to change the output. Multiple development environments alone make this a hassle. Even if you are retrieving a query from a CFC into a CFML template, the change can at least be made in your CFML editor of choice. (For more on a comparison of CFML and JSP, see Vince Bonfanti's article, "Making the Case for CFML," in CFDJ, Vol. 5, issue 6.) As far as the other frameworks such as Velocity and Struts, simply put, these are J2EE-only frameworks. I know there are a very few people out there using Struts with CFMX, but in general I wouldn't recommend it. CFMX offers more services and a better (in my opinion) framework, and this only adds a third element to hybrid applications. What you will end up with is a hydra, not a hybrid.

    Conclusion
    Overall, this is just a start - Hybrid Best Practices 101. The truth is that hybrid applications are only in the infancy stage - J2EE developers are starting to realize the RAD capabilities that CFMX can add to their applications and ColdFusion developers are realizing the power and control they can add using J2EE. I encourage any and all developers (both J2EE and CFMX) to contribute their thoughts on this matter in the Macromedia and CFDJ forums.

  • Comments (1) View Comments

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


    Most Recent Comments
    Rich Rosen 11/21/03 01:25:51 PM EST

    It seems your mailbox isn't yet overflowing about this one, but let me be the first to STRONGLY disagree. First, regarding JSPs: I myself had a long period of disdain for JSPs--especially the monolithic bloated variety overstuffed with Java code scriptlets that rendered them unmaintainable. Enter JSTL--wherein the Java world (which had heretofore expressed so much disdain for ColdFusion and its advocates) catches up to CF by building the very kind of STANDARDIZED tags (for iteration, conditional processing, etc.) that ColdFusion had all along, complete with an expression language that simplifies access to session and request attributes.

    This, of course, facilitates participation for such pages in an MVC framework--like Struts. But one thing often not recognized about Struts is that it is ultimately view-agnostic, meaning that it doesn't care what approach you use for your View components, it could be JSPs, Velocity templates or... Cold Fusion pages! One of the beauties of CFMX/J2EE is that you can configure it so that it "plays nice" with the underlying J2EE server's session management features. Thus, items put into the session by a Controller component (e.g., a Struts Action) can be accessed directly by the ColdFusion page used as the View component associated with that Action! All this means you can create a well-structured Struts-based MVC application that separates access to and manipulation of content from the ultimate presentation of that content, and the presentation of that content can easily be performed by a Cold Fusion page.

    Finally, one of the most easily overlooked features of Struts is action mapping. In the Struts configuration file, you can specify simple URL paths (e.g., http://server/action/doSomething) that ultimately forward or redirect to a View component with a more complicated URL that might be subject to change (e.g., http://server/application/function/doThis.cfm) Action mapping means the name of the ultimate MODULE performing a task (be it ColdFusion, JSP, or whatever) may change, but the URL need not change along with it. Besides, you might want to take a JSP component and rewrite it in ColdFusion--action mapping lets you simplify modify the configuration to point to a different URL for the actual module while maintaining the same entry URL for the end user.

    RR