Thursday, October 08, 2009

Drupal's Website Down Error

If you get this error from Drupal:

Unable to use the MySQLi database because the MySQLi extension for PHP is not installed. Check your php.ini to see how you can enable it.

The php.ini is located at: /etc/php5/apache2/php.ini

I was trying to give a direct link to php modules for one of the Drupal modules and it just didn't work.
expand post

Sunday, September 20, 2009

Drupal 6 is SLOW

So Drupal 6 is incredibly slow right now. We, Adam and I, just installed a lot of modules and enabled them.

Setup is Debian 5 with Apache 2.

1st assumption
Database. Accessing the database could be the reason. Checking the logs (@ /var/log) of mysql reveals nothing, there is nothing there. Perhaps I didn't enable logging. I'll check on that later.

2nd assumption
Modules. Let's disables all the modules! It helped just a tiny bit. In the process of this I disable all caching options of Drupal.

So I took a day or so break to think it over, maybe I'm over thinking this. Check on the website again and it's fast! Except, when you click on the administration URL it's very slow. Here's the reason why on the Drupal support forum:

"cog.rusty - February 21, 2009 - 13:50

The admin pages in Drupal 6 are slow because they do perform a lot of housekeeping and rebuilding (thousands of queries, as you noticed, and these are not just cosmetic). Caching probably won't help with that.

If it is unworkable, disabling the update status module will probably help a bit, and also there are open issues for reducing the number of queries in next updated, but don't expect the D6 admin pages to become snappy. They take the hit for some tasks which make the user part of the site more reliable.

About the normal site pages... the usual optimization methods should apply."


Alrighty then, let's just optimize the webpage.

Installed some tools to help me:
Life-of-Request Info extension
Devel module (where is this log file?)

1st optimization:
Let's optimize PHP by installing the APC package (read about it here):
Here's a tutorial on using APC.
http://www.easywebdns.com/tutorials/Linux/php/APC_ON_DEBIAN_LENNY

Access to main drupal as webmaster:
1st try: 1.3 s
2nd try (browser's cache cleared): .661s
3rd try: 0.877s

As a non user: 0.536s


Let's enable all the modules:

main page: 1.114s - 1.124s
content generated pages: ~.224s at most < .5s (no pictures or anything heavy just texts)

Yay, it's faster!



expand post

Wednesday, September 03, 2008

Setting up Debian Virtual Private Server

I recently went through the joy of setting my new virtual private server. Being new to server administration, it's been quite an adventure (and quite a bit of frustration).

I've learned quite a few lessons on setting up various things and I'll share my experience over the next few entries as I progress and learn more. On my checklist of things (some are done, some are not), I have:
  • Firewall - iptables
  • SSH - sshd
  • Webserver - Apache2
  • FTP server - ProFTPD
  • DNS entries
  • Mail server (Virtual Mailboxes, Webmail)
  • Various Languages - Python, PHP, PERL, etc...
  • Various Apps - emacs, git, dvtm, etc...
My server is running Debian Etch.
expand post

Thursday, September 21, 2006

Starting Lisp, Installing SLIME (on windows)

First things first, getting a lisp development environment set up. After looking around the web for a while, I arrived on SLIME: The Superior Lisp Interaction Mode for Emacs. Installing everything’s pretty simple, mostly because there’s really nothing too much to install.

I’m using GNU Clisp 2.39, GNU Emacs 21.3 and SLIME 2.0.

Simply unzip these where ever you want, in my case I put them all in c:\lisp
At this point, if you read the helpful README file, you’ll be told to put the following code into ~/.emacs

(add-to-list 'load-path "~/hacking/lisp/slime/") ; your SLIME directory
(setq inferior-lisp-program "/opt/sbcl/bin/sbcl") ; your Lisp system
(require 'slime)
(slime-setup)

The only problem is, where is this .emacs file? And what slashes do we use in windows?
The answer to the first question is trivial, let emacs find it for you. The second, use forward slashes.

  1. run “runemacs.exe”

  2. use the C-x C-f (ctrl+x, then ctrl+f) command to open ~/.emacs

  3. copy and paste the above into it (C-y is equivalent to pasting in emacs)

  4. replace the default paths with your own paths, in my case, they are: c:/Lisp/slime-2.0 and c:/Lisp/clisp-239/clisp.exe

  5. save the file using C-x C-s. (it turns out the file is created at c:\.emacs)



Now that you have everything set up, restart emacs (I’m not sure if this is required, I just restarted it) and start slime using M-x slime (alt+x, then type "slime"), if everything’s successful, you should see a Lisp interpreter console waiting for you.

As for me, I’m going through the (free online) book Practical Common Lisp by Peter Seibel.
expand post

Tuesday, September 19, 2006

Giving up (on) Java

Creating a web application in Java was fun, for a little while. Then the novelty of frameworks like Hibernate wore off, and I found myself programming the same functions in different Managers - over, and over again. It got tedious.

Maybe I don’t really understand how to use the frameworks properly, or maybe I didn’t choose the right framework, but I feel that there is something I need from this tool that it isn’t provided for me. I am looking for a different language. From my readings, Lisp seems like it may just fit my needs.

Lisp is described as a “programmable programming language”. I’m not entirely sure what this means, but it sure does sound exciting. Another exciting thing is that a lot of really smart people seem to be using it and promoting it as a very productive language. (Not just Lisp people, but also people who have many years of experience with modern languages like C/C++/C#/Java).

The primary problem I see with Java is that it seems as if it wasn’t designed for a single person to create complicated applications. All the frameworks and segmentation of code make it the perfect language for a bunch of programmers to build large systems in. This is not what I’m looking for now, so I’m going to keep looking for a more suitable tool to build what I need.

(there are a myriad of sites describing Lisp to different degrees, just search for it)
expand post

Tuesday, April 11, 2006

Ant scripting with Groovy

I've been playing a lot with Ant lately, and while it's a great tool - I like to think of it as the duct tape of Java programming - the restrictions of its XML format can make it a pain to use it for more complicated things. Yes, you can always write an Ant task to do what you need, but that has its disadvantages too - you need to worry about imports, compiling it, adding the jar to the classpath, adding a taskdef... a lot of work for what should be a simple scripting operation.

One possible solution - the Groovy Ant Task.

Here's a very simple example of the power Groovy brings to Ant. Let's take your standard Ant echo task:

<echo message="Ant is great"/>


There are several ways to write this using the Groovy task:

<groovy>
ant.echo(message:"Groovy is great")
</groovy>

or

<groovy>
ant.echo("Groovy is great")
</groovy>

or even

<groovy>
println("Groovy is great")
</groovy>

This might not seem like it's worth the trouble... but keep in mind that the string "Groovy is great" can be treated as a Java string for all intensive purposes... and manipulated with any of the Java methods. Not exactly trivial to do that using only Ant.

Let's try something more complex. I need to apply a XSL transform to all the XML files in a folder (quite achievable with Ant tasks) and create a simple HTML file with links to all the transformed files (not that easy using Ant). This is part of a Canoo Webtest Ant runner script, so ignore any of the specifics.

<groovy>
def scanner = ant.fileScanner {
fileset(dir:new File(properties.get('webtest.config.resultpath'))) {
include(name:'**/*.xml')
}
}

resultFile = new File(properties.get('webtest.config.resultpath') + "/results.html");

resultFile.write("<html><body><h1>Canoo Webtest results</h1><ul>");

for (f in scanner) {
ant.echo(message:f.name){}
fileName = (f.name =~ "xml").replaceAll("html");
resultFile.append('<li><a href="'+fileName+'">'+fileName+'</a></li>');
ant.style(basedir:properties.get('webtest.config.resultpath'),
destdir:properties.get('webtest.config.resultpath'),
includes:f.name,
force:"true",
extension:".html",
style:properties.get('webtest.config.resultpath')+"/WebTestReport.xsl")
{
ant.param(name:"reporttime", expression:properties.get('report.time'));
ant.param(name:"title", expression:properties.get('ant.project.name'));
}
resultFile.append("</ul></body></html>");
}
</groovy>

Not TOO bad, hopefully. Let's break it down into parts:

    def scanner = ant.fileScanner {
fileset(dir:new File(properties.get('webtest.config.resultpath'))) {
include(name:'**/*.xml')
}
}

Nothing that couldn't be done using Ant here, this is just the fileScanner task. One thing worth noting is properties.get('webtest.config.resultpath'), which is the equivalent of ${webtest.config.resultpath}. Next:

    resultFile = new File(properties.get('webtest.config.resultpath') + "/results.html");

resultFile.write("<html><body><h1>Canoo Webtest results</h1><ul>");

This is just Groovy code... which isn't that different from plain Java code. Create a file and start writing to it. Again, here we're using the Ant property ${webtest.config.resultpath} which is defined elsewhere in the Ant project. Next:

    for (f in scanner) {
ant.echo(message:f.name){}
fileName = (f.name =~ "xml").replaceAll("html");
resultFile.append('<li><a href="'+fileName+'">'+fileName+'</a></li>');

Again, mostly just Groovy code. Iterate through all the files and add a link to them in the html file we're building. The fun part is fileName = (f.name =~ "xml").replaceAll("html"); - a simple regular expression to replace the xml extension in the file name to html. Lastly:

        ant.style(basedir:properties.get('webtest.config.resultpath'),
destdir:properties.get('webtest.config.resultpath'),
includes:f.name,
force:"true",
extension:".html",
style:properties.get('webtest.config.resultpath')+"/WebTestReport.xsl")
{
ant.param(name:"reporttime", expression:properties.get('report.time'));
ant.param(name:"title", expression:properties.get('ant.project.name'));
}

This is a straightforward translation of the Ant style task into Groovy syntax.

Just one step left. Because of all the < > signs in there, I couldn't figure out how to include this directly in the Ant file. So I saved it as formatresults.groovy, and called it with:

        <groovy src="${resources.dir}/formatresults.groovy"/>

That wasn't so bad! The Groovy code isn't really any harder to read than the Ant syntax; it doesn't need to be compiled, so the source is simply stored alongside the Ant file, and modifications aren't any more difficult than changing the Ant script itself; and best of all, it allows much greater flexibility than the traditional Ant format.

So far I've used snippets of Groovy code inside an existing Ant script. As the Groovy site shows, it's quite possible to go to the logical extreme and write the entire Ant script as Groovy code - or have a Groovy script with calls to Ant tasks in it, really.

I guess the above is just a really longwinded way to say: if you're using Ant for anything more complex than a simple build script, take the half an hour to set up and play with Groovy a bit. It's well worth it.
expand post

Friday, March 31, 2006

Multiple Values in a Single Valued Form Field

There are times when you wish to have a single valued form field pass multiple values. For example, maybe you want a radio button to pass in a height and a width value at the same time. It wouldn’t be too hard to just pass in a comma separated list of values in predefined order and then parse them in the backend, but that would be very error prone and not too elegant. Another approach is to use something similar to the http GET request where you use parameter1=value1¶meter2=value2 style and then extract the values in the backend. This approach also involves some ugly string manipulation.

Here’s an example from work:

The existing application passes in a customer_order_id to the backend which is specific to a customer. We wish to extend it to also handle generic orders which are identified as order_id. How do we identify if the value passed in is a customer_order_id or an order_id? Having already rejected the two possible solutions that I’ve outlined above, I thought about perhaps having negative / positive numbers to distinguish between the two, but that’s way too hacker-ish.

The solution I arrived at involves using multiple hidden fields and referencing them from the single valued for object:


<form>
<ol>
<li><input type=”radiovalue=”1> value 1
<input type=”hiddenvalue=” order_id-1value=”generic-order-1>
</li>
<li><input type=”radiovalue=”2></input> value 2
<input type=”hiddenvalue=”order_id-2value=”generic-order-2>
<input type=”hiddenvalue=”customer_order_id-2value=”customer-order-2>
</li>
<li><input type=”radiovalue=”3></input> value 3
<input type=”hiddenvalue=”customer_order_id-3value=”customer-order-3>
</li>
</ol>
</form>


Then, in the backend, I only have to check the corresponding hidden field for the value.
expand post

Monday, March 20, 2006

Struts, Tiles and Validator

Just a bit of background for my next few entries: At work, I've been designing the front end structure for some new pages that we are introducing. We have decided to start using some new technology (for us), namely Tiles and Validator. Since the existing framework is using Struts 1.1, I am confined to using earlier versions of Tiles and Validator. For the new designs, I have kept several goals in mind:
  • Separation of business and view
  • Reuse of components
  • More configuration, less hard coding
First things first, creating a stand alone application to play around with the various technologies: Struts, Tiles, Validator, JSTL. I am using the Struts 1.1 package
  • The basic web app

    First things first, creating a basic webapp to play around with. For this step, I started out by using the struts-blank .war file included in the struts package (/webapps/struts-blank.war).

    Since getting compiling in eclipse was a bit of a hassle (at least it was for the one included in the 1.1 package), I'll go over it here. unzip the struts-blank.war file into a working folder, start up eclipse, create a New Java Project, pick a project name (e.g. struts-test), select "Create project from existing source" and using the directory that you expanded your struts-blank into, click on "finish".

    Next, right click on the /WEB-INF/src folder in the Package Explorer view and select build path > Use as Source Folder. For this project, we'll use Ant to build the project, go ahead and show the ant view (Window > Show View > Ant). You should see an ant view on the right side of your main editor, drag the /WEB-INF/src/build.xml file into the ant panel.

    Using the default build script, if you try to generate a war file using the dist target, you'll get the following warning: Warning: selected war files include a WEB-INF/web.xml which will be ignored (please use webxml attribute to war task), if you then try to deploy the generated war file, the application won't deploy property. To fix this, add an <exclude name="**/web.xml" /> line in the <war> task in the dist target. This will prevent duplicate web.xml files.

  • How hard is it to get JSTL to work.. Properly!?

    There are four main parts to getting JSTL working, if you leave out one or more of these, like I did, you're page will most likely not work. First, you need both jstl.jar and standard.jar, in addition you need to declare the taglib at the top of any JSP pages that you intend to use JSTL on:


    <%@ taglib prefix="c" uri="http://java.sun.com/jspjstl/core" %>

    or


    <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>

    if you are using an older version. For the other, non-core, JSTL tags, you'll need to add/use their respective taglib declarations.
    You can put a taglib declaration in your web.xml file, but I've got my applications working without them:


    <taglib>
    <taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
    <taglib-location>/WEB-INF/c.tld</taglib-location>
    </taglib>

    Personally, I like to keep my *.tld files in their own seperate folder, but the sample struts-blank webapp puts them in the WEB-INF directory along with the XML configuration files.
  • Playing With JSTL

    Now that we finally have JSTL set up, let's experiment and see what it can do.

    I started out using a single JSP, the index.jsp file found in the root project folder. I set up some classes that I wanted to play with inside a java scriptlet at the top of the JSP file:

    <%
    class Outer {
    private String name;
    private java.util.List inners;

    public String getName() {
    return name;
    }

    public java.util.List getInners() {
    return inners;
    }

    public void setName(String name) {
    this.name = name;
    }

    public void setInners(java.util.List inners) {
    this.inners = inners;
    }
    }

    class Inner {
    private String value;

    public String getValue() {
    return value;
    }

    public void setValue(String value) {
    this.value = value;
    }
    }

    Outer o1 = new Outer();
    o1.setName("outer 1");

    Inner i1 = new Inner();
    Inner i2 = new Inner();
    Inner i3 = new Inner();

    i1.setValue("inner 1");
    i2.setValue("inner 2");
    i3.setValue("inner 3");

    java.util.List ins = new java.util.LinkedList();
    ins.add(i1);
    ins.add(i2);
    ins.add(i3);

    o1.setInners(ins);

    pageContext.setAttribute("out1", o1);
    pageContext.setAttribute("test", "Testing String");
    %>

    I also included some code to set up a few objects. To access the objects, we have to place them into the session in one of the scopes: application, session, page or request

    I'll place my object in the default (page) scope and try to access it using the JSTL c:out tag:

    <c:out value="${test}"></c:out>

    Works fine and displays "Testing String" as we would expect, but:

    <c:out value="${out1.name}"></c:out>

    will, instead of accessing the getName() Javabean method and returning our name, reward us with a JspException:

    javax.servlet.ServletException: javax.servlet.jsp.JspException: An error occurred while evaluating custom action attribute "value" with value "${out1.name}": An error occurred while getting property "name" from an instance of class org.apache.jsp.index_jsp$1$Outer (java.lang.IllegalAccessException: Class org.apache.taglibs.standard.lang.jstl.ArraySuffix can not access a member of class org.apache.jsp.index_jsp$1$Outer with modifiers "public")

    What happens here is the tag tries to access the getName() method of the class, but cannot because the class is not public. This is easy enough to fix, just extract our two classes into their own Java class files. We then import these classes into our JSP and our code works as expected:

    <%@page import="com.adamdou.fronts.dummy.Outer"%>
    <%@page import="com.adamdou.fronts.dummy.Inner"%>

    Next, try doing some fancier things like displaying all the Inner items in our Outer item:

    <h2><c:out value="${out1.name}"></c:out></h2>
    <ol>
    <c:forEach var="in" items="${out1.inners}">
    <li><c:out value="${in.value}" /> </li>
    </c:forEach>
    </ol>

    Once you get JSTL up and running, it's pretty simple to experiment with different things, there's also a plethora of tutorials online such as the IBM JSTL Primer, a simple online search should turn up quite a few more.

That's it for now, next time I'll talk about some interesting adventures I've had with the Commons Validator.

expand post

Monday, March 06, 2006

The SUN Website

I was starting to write about something technical, but...

I've had a very interesting experience with the SUN website lately.

It all started when I tried to download the JSTL files.

Naturally, I started out by searching for JSTL on Google and was redirect to SUN's official JSTL page, http://java.sun.com/products/jsp/jstl/

Clicking on the Downloads link, I find that I can't just download a simple package and be done with it, instead I receive the joy of choosing between several different implementation. I instinctively go for the ones that promise JSTL 1.1

Selecting the J2EE 1.4 SDK link, I'm appalled to find that there is, again, no simple way to just download a simple package that could be extracted to a j2ee_sdk_1.4_03 folder, but no such luck. All the available download options include some sort of IDE or application server (which is not only useless, considering that I already have 2 application servers that both perform better than the ones from SUN) http://java.sun.com/j2ee/1.4/download.html

Furthermore, right underneath the first package, are the components of its make up. It eludes me how the Sun Java System Application Server PE 8.2, JDK 5.0, Platform API Docs and Samples Bundle combine into a J2EE SDK, much less a J2EE 1.4 SDK

Back to the main JSTL page, I tried getting the Java Web Services Developer Pack (Java WSDP). Downloaded and installed it, but alas, there's no mention what-so-ever about JSTL in any of the documentation for the WSDP.

Finally, I decided to give the Jakarta Taglibs a shot, about 2 minutes later, I have an implementation of JSTL 1.1 in form of the package jakarta-taglibs-standard-1.1.2. (http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi)

Admittedly, I should have known to look at the apache jakarta project first, but the SUN site makes it very difficult for newcomers to locate required resources for development.

</rant>

expand post

Firefox extension development

As some of you might know, while Adam's trying to make some sense of Hibernate for our Duckstein project, I've started playing around with a side project that happens to be a Firefox extension.

Much to my surprise, the experience so far has been quite enjoyable. Documentation is quite good - a quick tutorial on how to set up a Firefox extension for development, the excellent XUL tutorials from XULPlanet, and I had a simple tic-tac-toe extension working in under two hours. Most of those two hours, as usual, were spent on silly mistakes - and a lot of it could've been avoided if I remembered to use the error console earlier (or if I knew JavaScript properly in the first place).

It seems pretty simple to modify any pages Firefox loads before they're displayed. The fun part of the extension, however, is to interact with pages that are updated dynamically after they're loaded (like, maybe, by XMLHttpRequest, hmm?) This has proved to be somewhat more difficult. I can think of two general approaches... one is to set up an event listener that notifies the extension whenever an AJAX request is sent/received or when the page is modified... the other is to "simply" add my own javascript code to the existing JS code on the page that handles the requests. The first solution seems (in theory) simpler, while the second seems more elegant... I'm not sure which one would be more robust (e.g. resistant to changes made to the site). So far the first solution has been a dead end, however... it seems that it should be enough to add a DOMSubtreeModified listener to the element I'm interested in watching - but I can't even figure out if Firefox supports this listener.

I've also come across a few pretty cool extensions. The first is Firebug (home page), an excellent error/debug console for Firefox that also supports XMLHttpRequests - whenever I'll work on an AJAX project this will be invaluable, and the perfect complement to the also-excellent Web Developer extension which I've been using for a while already. Another is Customize Google - should be self-explanatory. Looking at the source code for these two should help me figure out how to get my extension working, as well.

The third neat extension is Firefoxit - a sort of desktop-inside-Firefox that can hold widgets. Fun stuff.
expand post

Sunday, February 26, 2006

Tomcat & Tapestry

One thing that has been frustrating over the past few months - both for Project Duckstein and at work - is that I still don't know an "elegant" way to reliably redeploy a WAR file in Tomcat. Simply replacing the WAR in the webapps folder doesn't usually work... neither does undeploying/redeploying through the Tomcat manager. Sometimes it works, sometimes it doesn't... more often than not the only reliable way is to stop Tomcat, delete the WAR and the exploded folder, compile the new WAR, and start Tomcat. Even the ant tasks to stop/start Tomcat don't seem to work, because... well, I forget why, but they don't.

The very kludgy way I have right now is to use ant to stop/start the Tomcat service itself:



<target name="tomcat-netstart">
<exec executable="net">
<arg line="start tomcat5"/>
</exec>
</target>

<target name="tomcat-netstop">
<exec executable="net">
<arg line="stop tomcat5"/>
</exec>
</target>


The target for a full deployment, then, is



<target name="full" description="Full deployment" depends="tomcat-netstop,clean,dist,tomcat-netstart"/>


Not exactly the most elegant solution... we still need to figure out a better way to do this.

Now, for development, this is even worse. The above mentioned process takes up to 30 seconds on my (fairly old) computer... plus another 10 seconds or so for Tapestry to first load the pages. Trial-and-error coding thus becomes a very, very painful process.

The Spindle Eclipse plugin is supposed to alleviate this, along with goodies like syntax highlighting, auto-completion, and other stuff that makes the whole process more sane... unfortunately Spindle is not yet available for Tapestry 4. I did, however, notice a post on the Spindle blog linking to instructions for setting up the Eclipse Web Tools Platform to work with Tapestry. The largest benefit at this stage of development is, by far, the automatic deployment of any changes made to classes or resources. That's right, no server restart... just save the changes and see them take effect right away. This is how I have my Eclipse set up at work, and I was really missing this capability while working on Duckstein so far.

So I am now downloading the WTP... let's see how well it works.
expand post

Thursday, February 23, 2006

Floating Forms with CSS

More than likely in any medium or large web application will have a page or two filled with form input boxes.

I’ve just had the pleasure of creating several of these pages.

Now, standard practices was to create a table and stick the labels and field into it. While this is a satisfactory solution, it suffers from several issues: it doesn’t allow you to easily more the fields around and it doesn’t work when you don’t want the fields to all line up.

A good solution that address these issues is the floating form fields. Here’s a small sample of what the form should look like:



here's the HTML code for it:


</style>
<div style=”background-color:#eee; width: 400px;”>
<div class=”field”>
<p>First Name</p>
<input type=”text” size=”20”></input>
</div>

<div class=”field”>
<p>Last Name</p>
<input type=”text” size=”20”></input>
</div>

<div class=”field”>
<p>Email</p>
<input type=”text” size=”30”></input>
</div>

<div style=”clear:both”></div>

<div class=”field”>
<p>Phone</p>
<input type=”text” size=”16”></input>
</div>

<div class=”field”>
<p>City</p>
<input type=”text” size=”15”></input>
</div>

<div class=”field”>
<p>Postal / Zip Code</p>
<input type=”text” size=”6”></input>
</div>

<div style=”clear:both”></div>
</div>


and CSS code:


body {
font-family: verdana;
font-size: 12px;
}

.field {
float:left;
padding: 5px;
}

input {
border:1px solid #aaa;
font: 12px;
}

p {
margin: 5px;
}


Basically, what’s happening here is that each label along with its field is put into a div layer and then floated left so that they stack onto each other.

Notice that there is an empty div used to create a new line; this is not an ideal situation as it adds to the HTML code bloat (here’s a solution to that, but it seems to be too much of a CSS hack), but it’s a simple solution to the problem of creating new lines (and also another problem where the floating element hangs out of the container, IE does automatic clearing, but that’s in violation of the W3C standards)

Now, the good thing about these floating fields is that you can rearrange them at will without having to shift the other fields.

An added benefit of this is method is that if the container shrinks, the fields will automatically move to a new line, reducing horizontal scrolling.

This is just the basics, there are many variations, have fun.
expand post

Monday, February 20, 2006

Rails, Grails, Sails, Nails, Fails...

So this entry might not be entirely coherent... it's Monday morning, don't expect it to make much sense.

This morning I read a message on the Canoo Webtest mailing list, about Grails:

The upcoming Grails project will include sophisticated support for Canoo
WebTest.

Grails is an open-source application framework based on Groovy. see
http://grails.codehaus.org .

Grails allows easy defintion of domain classes, views, and controllers from
scaffolded artifacts. For these artifacts, it also scaffolds WebTests, see
http://grails.codehaus.org/Functional+Testing .

Grails is comparable to Ruby on Rails but runs on the Java platform
leveraging the power of J2EE, Spring, and Hibernate. It even works with
existing Java domain classes and mappings.


Now, a small side note here. Canoo is, in my opinion, the best end-to-end functional web testing solution currently available, and has been adopted with great success at my company (Watir and Selenium should probably be mentioned here as well). Anyway, point is - I respect the Canoo folks, and when they put their support behind something, that is a good reason to take a look at that project.

Of course, Grails doesn't seem to be the only Ruby-on-Rails-in-Java project (RoRiJ? what a dumb acronym. I promise not to use it again). There's also Sails, and the two projects seem to be aware of each other. And, I'm assuming, there are many others, at varying stages of completion.

What's the point of this rant, completely unrelated on our progress on Duckstein (more on that later :p)? Well, it's two-fold. First, I'm usually pretty skeptical of hype, so I never really took the whole Ruby on Rails deal seriously. I've wanted to check it out to see what all the fuss was about, but wasn't sure whether to expect actually finding anything of substance... but if imitators are popping up left, right and center, there has to be something there. Second, because I want to follow these projects in the future... and if I don't make a note of them somewhere, I'll completey forget of their existence by lunch, at best :p
expand post

Wednesday, February 15, 2006

You kicked my browser.

You know, Sometimes we wonder why as programmers we have to deal with six browsers, and multiple versions of each browser. Why doesnt someone simply write a super browser of sorts? You have the major players - IE, Firefox, Safari, Konqueror, Opera, and Netscape 4 (heh.. man is netscape 4 in a category of its own): Why doesn't someone write a plugin based browser - like a super browser. The idea: Write a parent that will have plugins for each of these major child browsers.

Then: Let coders specify (sort of like specifying fonts), which browser their page works best on, and then which is the next best browser for their page and so on.. This super-mother browser will pick up this tag and open that page in the appropriate tab - maybe even open it in the same screen (hide a layer.. show the next?), making it transparent to the end user.

This is ofcourse a massive hack proposition until everyone starts conforming to standards.
expand post

User authentication using Tapestry - Part 3

This is the third, and probably final, entry on user authentication with Tapestry. And only one day after the last one... man, I'm on a roll!

This entry is about tackling the big bad dragon of object-oriented programming, and coming up with something that a) abstracts some of the plumbing work of user authentication so we don't have to do it on every page in the application, and b) can be used for different Tapestry projects without any changes.

I've added two new classes that should be application-independent (though not Tapestry-independent). One is a wrapper user object that we can store in the session as an ASO; the other is an abstract Tapestry page class that holds what we need to deal with the ASO.

First, the user class:



public class TapestryUser {
private boolean loggedIn;
private Object user;
public TapestryUser() {
user = null;
loggedIn = false;
}

public boolean isLoggedIn() {
return loggedIn;
}
public Object getUser() {
return user;
}
public void setLoggedIn(boolean loggedIn) {
this.loggedIn = loggedIn;
}
public void setUser(Object user) {
this.user = user;
}
}


Pretty simple. According to Enjoy Web Development with Tapestry, ASOs must have a constructor with no arguments (check), and implement Serializable. I actually forgot about the Serializable part until I started writing this... but it seems to work. So, who knows - if I run into any problems later, this'll be one thing to check, I guess.

Next, the page class:



public abstract class AuthenticatedPage extends BasePage {

@InjectStateFlag("tapestryUser")
public abstract boolean getTapestryUserExists();

@InjectState("tapestryUser")
public abstract TapestryUser getTapestryUser();
public abstract void setTapestryUser(TapestryUser tapestryUser);

/**
* Return true if the current session belongs to a logged
* in user.
* @author Alex
*/
public boolean getLoggedIn() {
if (getTapestryUserExists() && getTapestryUser().isLoggedIn())
{
return true;
}
else
{
return false;
}
}

/**
* Store user in the httpsession as logged in.
* @author Alex
*/
public void setLoggedIn(Object user) {
getTapestryUser().setUser(user);
getTapestryUser().setLoggedIn(true);
}
}


Again, pretty simple. This simply takes all the stuff we put in our Home class last time, and packages it nicely for easy reusability. The last step is to declare the ASO for Hivemind:



<?xml version="1.0"?>
<module id="com.kharthick.beer" version="1.0.0">
<contribution configuration-id="tapestry.state.ApplicationObjects">
<state-object name="tapestryUser" scope="session">
<create-instance class="com.kharthick.authentication.TapestryUser"/>
</state-object>
</contribution>
</module>


Using these two classes is even easier. For any page in our Tapestry application that has a login form, the page definition will start with something like:


public abstract class Home extends AuthenticatedPage


(remember that previously the Home class extended BasePage). Now you can accept the user login/password and verify them any way you want to, and simply call setLoggedIn once you're happy:



MutableUser mutableUser = DummyFactory.getMutableUser(username, password);
if (mutableUser != null)
{
// remember that this user has logged in.
setLoggedIn(mutableUser);
return getHome();
}


Pages that only need to check whether the user is logged on, and not actually log on, are even easier. There is NO Java code needed beyond "extends AuthenticatedPage" instead of "extends BasePage", and the page specification can simply do something like:



<span jwcid="@If" condition="ognl:loggedIn">


Accessing any user object properties or methods is as simple as value="ognl:tapestryUser.user.username" as long as the page class extends AuthenticatedPage.

This mechanism doesn't provide any information beyond whether the user is logged in or not, but it does provide at least two ways to extend it for more complicated authentication (such as permissions). One way would be to extend AuthenticatedPage with application-specific methods; the other would be to keep such methods in the application-specific user object.

Well, there you have it! By using a clever combination of the Structural-Beam-Under-Tunnel and Monk-Under-Tree-Feeding-Small-Bird design patterns, we have achieved OOP nirvana. One down, only four more ${vowel}-oriented-programming paradigms to go!

This post is part of a series:

User authentication using Tapestry - Part 1
User authentication using Tapestry - Part 2
User authentication using Tapestry - Part 3
expand post

Belated Introduction

Hi, for all those who don't know me, and I would say that's a lot, I'm a high school senior (soon-to-be college freshmen) that is "deeply" interested in computer science and engineering. I am, however, not as knowledgeable as the other chaps(lol) that contribute. Learning right now is my main concern. Well, let's see if I'll ever contribute anything meaningful.. lol

I do have a project I'm working on, a game called Primitive Wars, that I am overhauling right now. It will, in my hopeful vision, be a bona fide turn based strategy that has elements similar to the Advance Wars series. Any artists, musicians, story writers, programmers, or game designers are welcome to help me. =]

Ciao for now.
expand post

Fun With Javascript

I recently had some fun with animating a div with javascript.

I was just playing with showing/hiding a div tab and decided to try animating it growing...

I created a anim function for animating, but alas, it didn't work. well, I couldn't figure out how to pass objects using the javascript setTimeout() method.

after some searching, I found this interesting site and began writing this code:


function getAnimDiv(obj, change, current, end) {
return (function() {

current += change;
if(current >= end) {
obj.style.height = end+"px";
} else {
obj.style.height = current+"px";
anim(obj,change,current,end);
}

});
}

function anim(obj, change, current, end) {
var animRef = getAnimDiv(obj, change, current, end);
setTimeout(animRef, 10);
}


I'll leave it's inner workings to the reader, but I will tell you that obj is the div object.

Is there a better way to do this? Maybe, if you figure it out, let me know.

Oh yeah, this works in both IE and Firefox.
expand post

Tuesday, February 14, 2006

User authentication using Tapestry - Part 2

For my exciting sequel to the first part of User authentication using Tapestry, I will try to cover how to actually do something based on whether the user is logged in or not. Amazing, isn't it? (just wait till part three - we'll get to defeat the evil forces of Sauron! ...or something equally adventurous).

First, recall that last time we stored the user object in an application state object, which is accessed by Tapestry using something like this:



@InjectState("mutableUser")
public abstract MutableUser getMutableUser();
public abstract void setMutableUser(MutableUser mutableUser);


When the user successfully logs in, we set this to something that makes sense, in the hope that we'll check it later to verify that the user is logged in. The way we set it was with:



getMutableUser().copyFrom(mutableUser);


Now, notice that this is the very first time we're calling getMutableUser() to access the ASO (don't confuse it with the call to DummyFactory). So where is it coming from, since we never created it? Well, it turns out that Tapestry (or Hivemind more likely, I'm never too clear where all this stuff is handled) initializes the object the very first time it's accessed. This would presumably be why it needs an empty constructor.

So how do we check if the user is logged in, if trying to access the MutableUser object actually creates it? Pretty simple - with a little beauty named a State Flag, which is defined like this and does pretty much what you'd expect it to:



@InjectStateFlag("mutableUser")
public abstract boolean getMutableUserExists();


OK, enough chit-chat - let's get to actually doing something with this information. I made the login box on the home page show up if the user is not logged in - as soon as the user logs in, I made the page disappear and show a message welcoming the user, and a logout link.

Here's the HTML (true to form, I completely failed to separate all the parameter bindings into the page definition file... maybe for the final code :p)



<span jwcid="@If" condition="ognl:loggedIn">
Welcome, <span jwcid="@Insert" value="ognl:mutableUser.username"/>!<br>
<span style="font-weight: bold;">User Actions: </span><br>
My Profile<br>
Manage Users<br>
<a href="#" jwcid="@ExternalLink" page="EditMeeting" parameters="ognl:-1">Create Meeting</a><br>
<span jwcid="@ServiceLink" service="literal:restart">Logout</span><br>
</span>
<span jwcid="@Else">
<form jwcid="loginForm">
Username:<br>
<input type="text" jwcid="username"/><br>
Password:<br>
<input type="password" jwcid="password"/><br>
<input name="Login" value="Login" type="submit"/><br>
</form>
<span style="color: red"><span jwcid="errorMsg"/></span>
Don't have an account?<br>
<a href="register.html">Register!</a><br>
<br>
</span>


Don't think there's anything fancy - the only thing worth noting is the condition of the @If component: condition="ognl:loggedIn". Here's the corresponding Java code for this condition:



public boolean getLoggedIn() {
if (getMutableUserExists())
{
return true;
}
else
{
return false;
}

}


Now, there are two things worth noting here. First, the condition is ognl:loggedIn, not getLoggedIn. I'm cheating here a bit, because I'm counting on Tapestry's behaviour to call a getter for a boolean named "loggedIn". The way I had this coded at first was something like


<span jwcid="@If" condition="ognl:loggedIn" listener="isLoggedIn">


where isLoggedIn actually set a private boolean field named loggedIn. This led to the strange behaviour that the login box would only disappear on the SECOND successful login (or once the resulting page after a login was reloaded) - which most likely indicates that a) the changes made by the listener take effect too late to affect the rendering of the if component, and b) I still don't really understand the whole page rendering cycle and form submission behind Tapestry.

The second thing to notice is that we're simply assuming the user is logged in based on getMutableUserExists(). This isn't a very safe assumption, since the ASO is created whenever it's accessed - a more valid check would be something like getMutableUserExists() followed by getMutableUser.isLoggedIn(). We don't really have a proper tapestry user object, so this isn't in yet.

Finally, how to log out? The simplest way would be (assuming we had a proper user object) something like getMutableUser.setLoggedIn(false). The somewhat more complicated way would be to remove the mutableUser object from the session - I still need to figure out how to do this. (TODO - update here if I figure it out!)

Of course, I chose neither of the above, in favour of the most PERMANENT way - we just destory the entire session! Brilliant, isn't it? All it takes is a ServiceLink to the restart service (did I mention how much I hate trying to find something in the Tapestry documentation?). The HTML, as seen above:



<span jwcid="@ServiceLink" service="literal:restart">Logout</span>


And that's that for today!

Coming up next: how to set up a more general user authentication system, or possibly some Tacos AJAX goodness.

This post is part of a series:

User authentication using Tapestry - Part 1
User authentication using Tapestry - Part 2
User authentication using Tapestry - Part 3
expand post

Perils of Enterprise Debugging

Debugging by itself is not an entirely un-enjoyable experience.
Debugging someone else’s code is less so.
Debugging someone else’s code in an enterprise environment where said person is long gone is a perilous activity at best.

There’s a defect at work. Only the first part of the page is loading up. The page is the last page on a sequence of pages.

Step 1. reproduce the defect on the remote server, ~ 5 minutes
Step 2. look at logs on the remote server, ~ 5 minutes
Step 3. D’oh, can’t find any errors, load up latest version from source control locally, ~ 10 minutes
Step 4. Insert debug statements where I suspect the error occurs, ~ 1 minute
Step 5. Start up local Weblogic server, compile and deploy, ~ 10 minutes
Step 6. Test locally, ~ 5 minutes
Step 7. Insert more debug statements, compile, deploy, test, rinse and repeat ~ 20 minutes

So, after about an hour and a half, I find the cause of the error.

A type in the name of resource.

Considering everything, this bug isn’t too bad.
expand post

Monday, February 13, 2006

World's most useless class?




public class Counter {
private int i;
/**
* @return Returns the i.
*/

public void increment() {
this.i++;
}

public String getString() {
return Integer.toString(getI());
}

public int getI() {
return i;
}
/**
* @param i The i to set.
*/
public void setI(int i) {
this.i = i;
}
}


What is the point of this??

To avoid incrementing by something other than 1 by mistake? To make it more obvious that the variable is a counter or that you're incrementing (as opposed to the cryptic i++)? To pass the counter variable around? To be able to extend your counter's functionality in exciting new ways without affecting the code that uses it?

What's wrong with good old int i??

Discuss.
expand post