Sunday, February 22, 2004

Java Revisited

In quite an interesting turn of events this week, a Java application I wrote two years ago so impressed the company to which it was being presented that they want to buy it. Since this application also represented more or less the last line of Java code I've written before switching to a position where I do ColdFusion full time, I decided I better invest in the latest Java books and see what I need to do to update the application to modern Java standards. The results were actually an extremely pleasant surprise.


 


Java has changed quite a bit since I was last using it regularly, particularly in the arena of Java web application programming. Most notably is the addition of the the JSP Standard Tag Library (JSTL), which was designed in order to take a lot of common tasks that used to be a headache in JSP and encapsulate them into easy-to-use tags. (Sounding familiar?) I'm also pretty interested in the JSTL because you can now use Java tag libraries in ColdFusion, so I was curious to see if there's anything in the JSTL that might be useful in ColdFusion.


I was really struck with the numerous similarities between what CF does natively and what JSP does through the JSTL, but it really hit home when I got to the chapter in the latest O'Reilly Java Server Pages book that covers SQL and database access.


Prior to JSTL, developers were stuck rolling their own solutions to the extremely typical SQL interaction that happens in 99% of all web applications. Once you tackle it the first time all the subsequent times you have to do these sorts of things aren't *that* big a deal, but JSP was still lacking a native way to do this simply, which ColdFusion has had since day 1. The JSTL now contains a SQL tag library, which is an extremely welcome addition, and a quick code sample might make my point better for me than simply describing it.


The sample code in the book that introduces the SQL JSTL is a typical Employee database. I won't put the complete example in here, but let's take a look at an insert into the database of a new employee. This is the "action" page to which a JSP form for entering a new employee is submitted. First we import a couple of tag libraries, one for SQL functionality, the other for data formatting:



<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<%@ taglib prefix="fmt" uri="http:/java.sun.com/jsp/jstl/fmt" %>


Then we have to deal with the employee's hire date momentarily:


<fmt:parseDate value="{$param.empDate}" var="parsedEmpDate" pattern="yyyy-MM-dd" />

Then we grab the current date using a Date bean:


<jsp:useBean id="now" class="java.util.Date" />

Then we do our insert using the SQL tag library:


<sql:update>

INSERT INTO Employee

(UserName, Password, FirstName, LastName,

Dept, EmpDate, EmailAddr, ModDate)

VALUES (?, ?, ?, ?, ?, ?, ?, ?)

<sql:param value="${param.userName}" />

<sql:param value="${param.password}" />

<sql:param value="${param.firstName}" />

<sql:param value="${param.lastName}" />

<sql:param value="${param.dept}" />

<sql:dateParam value="${parsedEmpDate}" type="date" />

<sql:param value="${param.emailAddr}" />

<sql:param value="${now}" />

</sql:update>

For those of you who remember doing this sort of thing in Java two or three years ago, this may seem A) completely foreign, and B) very, very cool. Now let's look at this same action in ColdFusion just to drive my point home:


<cfquery name="qInsertEmployee" datasource="myDataSource">

INSERT INTO Employee

(UserName, Password, FirstName, LastName,

Dept, EmpDate, EmailAddr, ModDate)

VALUES

(<cfqueryparam value="#form.userName#" cfsqltype="cf_sql_varchar" />,

<cfqueryparam value="#form.password#" cfsqltype="cf_sql_varchar" />,

<cfqueryparam value="#form.firstName#" cfsqltype="cf_sql_varchar" />,

<cfqueryparam value="#form.lastName#" cfsqltype="cf_sql_varchar" />,

<cfqueryparam value="#form.dept#" cfsqltype="cf_sql_varchar" />,

<cfqueryparam value="#CreateODBCDateTime(form.empDate)#" cfsqltype="cf_sql_date" />,

<cfqueryparam value="#form.emailAddr#" cfsqltype="cf_sql_varchar" />,

<cfqueryparam value="#CreateODBCDateTime(Now())#" type="cf_sql_timestamp" />)

</cfquery>

Is Java starting to look more like ColdFusion? I think so, and personally I think this is a very good thing. The Java camp is finally starting to realize that while Java is exteremely powerful, it previously lacked a way to handle mundane, repetitive tasks such as this. Developers were rolling their own solutions of course, but then one application implements the exact same task completely differently than another, which can be a problem from a compatibility and maintenance perspective.


When I first got the word I was going to have to resurrect my long-forgotten application to prepare it for sale, I had mixed feelings. I remember being incredibly less productive in Java than I can be in ColdFusion, but I must say that the changes to Java almost have me excited about Java again! The JSTL of course has a ton more functionality that I won't go into at the moment, but suffice it to say that Java has come a long way in the last couple of years, and web application development in Java will no longer be the headache it once was. Why? Because ColdFusion had it right all along of course, and Java is finally starting to catch on. ;-)

Sunday, February 15, 2004

Further Clarification: Mach-II in a Shared Hosting Environment

A few more details came to light from a discussion on the Fusebox Forums, and thanks to Sean Corfield as usual for clarifying things.


To summarize, what the MACHII_APP_KEY variable does is sets the key in the Application scope struct that stores the data. In my case the issue I was seeing related to MACHII_APP_KEY was because I had installed the sample applications from the Mach-II site, and apparently others on my server had done the same thing, because unless I explicitly changed MACHII_APP_KEY to something other than the default (which just gets the path dynamically), it was apparently attempting to tap into someone else's key. Specifically I was seeing errors related to the application not being able to find MachII.framework.* CFCs, even though my copy of the Mach-II no longer has the default MachII.* calls anywhere in it.


The long and short of all of this is that in a shared environment you need to be careful about how you name your directories in your Mach-II applications because this directory name is in essence what determines the key in the application scope for your application. For names I think other people might be using (like the Mach-II sample apps) I've taken to putting the "SFS" prefix before everything (abbreviation for my company name, "Sixth Floor Software") and this seemed to do the trick. By the time my "real" project in a shared environment starts I should have these issues completely ironed out.

Mach-II in Shared Hosting Environments

It was bound to happen sooner or later--my next side project with Mach-II is going to live in a shared hosting environment, so I decided to do some preliminary work getting things up and running before the project really gets rolling. Up until this point I've been doing Mach-II work for i2 on dedicated servers, so I haven't had to worry about how CFMX finds the CFCs.


 


I personally felt that my hosting account with HostMySite was a little limiting (no ability to create my own mappings, for example, although they're happy to do it for you), so since my account with them was coming up for renewal anyway, I decided to try CrystalTech since I'd heard so many other CF developers say they were happy with them.


Please note that I'm a big fan of HostMySite in general--they have great tech support and I will continue to heartily recommend them to clients; I personally just wanted to try something different and liked the idea that CrystalTech let me set up my own mappings at will, and I also get more database space and have both SQL Server and MySQL databases for less money.


Just one quick complaint about CrystalTech: when I called in with some general problems with CFCs and my mappings working initially, I got a .NET developer on the phone with an extremely large .CHIP on his .SHOULDER. Some actual quotes from this guy:




  • "Sir, I'm a .NET developer. I'm not a newbie programmer so I know what I'm talking about."


  • "ColdFusion doesn't start looking for objects in your docroot, it starts at the System32 directory. I know because I'm a .NET developer."



  • Nevermind the fact that A) I wasn't calling about .NET, and B) that second statement isn't even TRUE in .NET (at least not in my experience on the two .NET projects I've done); my main issue with this guy is that he's supposed to answer my questions, not tell me how he's so much smarter than I am. Minor complaint but if you're on CrystalTech and get this guy on the phone, hang up and call back later. Extremely rude, extremely unhelpful, and just an out-and-out .JERK.


    Back to the topic at hand: Since the server I got put on at CrystalTech already had the mapping "MachII" taken, I had to set up a different mapping, which means you also have to alter all the Mach-II core framework files to reflect this mapping. This isn't anything a global search-and-replace can't handle, and once I got my bearings and had my mapping set up, I had Mach-II running fine with a different mapping.


    After taking an initial stab at this, since I recalled that MVCF used a variable as a prefix to all the CFC locations, I thought maybe I could save *some* of the work by setting up a variable for my mapping and using that variable where possible in the Mach-II core files. I say "where possible" because of course the type parameter in cfargument won't accept a variable, and neither will extends in your cfcomponent tag, so basically all that using a variable really gains you is a dynamic setting for your CreateObject methods and a few other minor things. After trying this approach I decided consistency was probably a better idea so I reverted back to using my mapping name in place of "MachII." in the core framework files.


    The only other thing I noticed that I had to do was set the MACHII_APP_KEY variable in my mach-ii.cfm file to the name of my mapping as opposed to letting it do GetFileFromPath(ExpandPath(".")). Again, this isn't a big deal, but since I've been on dedicated servers to this point I'm a little unclear as to exactly what the MACHII_APP_KEY variable does.


    I posted a message to the Mach-II forum on fusebox.org to get some other thoughts on this situation in general. Since building Mach-II apps on shared servers is probably something I'll be doing a lot of in the future I just want to make sure I'm doing it in the best way possible.


    The bottom line is getting Mach-II up and running in a shared hosting environment didn't take much time at all, and at least from what I can tell thus far, is working great. As I figure out more and more about using Mach-II in shared environments I'll be sure and pass along any tips, tricks, and "gotchas" I happen to experience.

    Wednesday, February 11, 2004

    Mach-II Presentation

    Here's the presentation I gave at the Dallas-Fort Worth ColdFusion User Group meeting last night, in either Keynote or PowerPoint format. If you look it over and have any questions, please feel free to send me an e-mail.




    intro_to_mach-ii.pdf
    Download this file


    Sunday, February 8, 2004

    Two Mach-II Projects Down, Many To Go ...

    After completing two relatively involved projects using the Mach-II Framework, I'm even more impressed with it than I was initially. Many, many of the old headaches that usually accompany large projects simply no longer exist in Mach-II projects, and maintenance is a breeze. I just had to add quite a bit of back-end administrator functionality to the Radica Games site and it went more quickly and more smoothly than practically any project I've worked on.


    I also just completed a rebuild of the i2 Careers site in Mach-II. This eliminated an expensive outside contract (and I mean EXPENSIVE ...), and required a fair amount of functionality to be built in a short amount of time (what's new?), so it was probably a little ambitious of me to take this on as my second Mach-II project. I'm either brave or stupid depending who you ask, so I boldly charged ahead with it, and everything came together without a single hitch. This project probably had a fair amount of shifting requirements to add to the quick turnaround, so Mach-II really saved my behind in a lot of ways. Requirements changes that previously would have been a complete disaster were comically easy with Mach-II.


    Given these great experiences I can definitely say that I'll be using Mach-II whenever I possibly can. At i2 I'll be doing the intranet and investor relations sites (another expensive outside contract eliminated!) in Mach-II, and the i2 User Group site and a rework of i2.com are coming up next.


    At some point I'm going to try and get more technical on this blog, share my thoughts and what I've learned, etc., but honestly right now I have too many projects on my plate to elaborate much further. I am giving a presentation on Mach-II at the Dallas-Fort Worth ColdFusion User Group meeting on February 10, so once I get that completed I'll put my Keynote presentation up here (I'll put up a PowerPoint version or something else for you unenlightened Windows folks ...) and hopefully that will get more people excited about what I think is a truly great application framework. Particularly if you're already doing a lot with CFCs, you owe it to yourself to check out Mach-II (and if you're not doing a lot with CFCs, why not?). The learning curve is pretty low and I think you'll find yourself being more productive and tearing out a lot less hair than you probably have in the past.