Pages

Sunday, June 29, 2008

JSF Custom Validator Example

I found another Sun Java Creator 2 example for using a custom validator. This may have also been an example from Creator, but I updated its project files to work with Netbeans 6.1. I updated the project so that the original visual JSF files can still be manipulated visually.





Here is a link to the Netbeans project: CustomValidatorExample.zip

Saturday, June 28, 2008

JSF Custom Message Example

I came across an old Sun Java Studio Creator 2 custom message example. This may have originally been an example project on the IDE. I am not sure so I can not make claim to doing the original coding. I did however bring it up to speed on Netbeans 6.1. I transferred the code and updated the project so that it will build and it works very nicely. The result is a page which prompts you for a value and should you submit it without one, it will pop up an error message.



NOTE: The application is not a Visual JSF example.

Here is a link to the Netbeans project : CustomMessage.zip

Java RandomAccessFile Example

Here is another example of how to use a common file handling mechanism in Java. RandomAccessFile is very powerful tool to open a file and find specific items in it. It also allows you to update, delete, or append data to the file. Developers become accustomed to using File for a number of operations, but I contend that using RandomAccessFile is more powerful and flexible.

In the code example and Netbeans project that follow, I create a file and append data to it. I print the data out, and then add the class name to the beginning of the file, append the existing data, and print it back out again.

I originally came across my work on it when I was learning Java many years ago. I re-examined it, tweaked it, and converted it to a Netbeans project.

1 /*
  2  * 
  3  * Blue Lotus Software, LLC
  4  * 
  5  * Copyright 2008. All Rights Reserved.
  6  * 
  7  * $Id$
  8  * 
  9  */
 10 /*
 11  * Copyright (C) 2008 Blue Lotus Software. All Rights Reserved.
 12  *
 13  * THIS SOFTWARE IS PROVIDED "AS IS," WITHOUT A WARRANTY OF ANY KIND.
 14  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 15  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 16  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 
 17  * BLUE LOTUS SOFTWARE, LLC AND ITS LICENSORS SHALL NOT BE LIABLE 
 18  * FOR ANY DAMAGES OR LIABILITIES
 19  * SUFFERED BY LICENSEE AS A RESULT OF  OR RELATING TO USE, MODIFICATION
 20  * OR DISTRIBUTION OF THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
 21  * BLUE LOTUS SOFTWARE, LLC OR ITS LICENSORS BE LIABLE FOR ANY LOST 
 22  * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, 
 23  * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED 
 24  * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE 
 25  * OF OR INABILITY TO USE SOFTWARE, EVEN IF BLUE LOTUS SOFTWARE, LLC 
 26  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 27  *
 28  * You acknowledge that Software is not designed, licensed or intended
 29  * for use in the design, construction, operation or maintenance of any
 30  * nuclear facility.
 31  */
 32 package com.bluelotussoftware.j2se.examples;
 33
 34 import java.io.FileNotFoundException;
 35 import java.io.IOException;
 36 import java.io.RandomAccessFile;
 37 import java.util.logging.Level;
 38 import java.util.logging.Logger;
 39
 40 /**
 41  *
 42  * @author John Yeary
 43  * @version 1.0
 44  */
 45 public class RandomAccessFileExample {
 46
 47     private static final String CLASSNAME = RandomAccessFileExample.class.getName();
 48     private static Logger logger = Logger.getLogger(CLASSNAME);
 49
 50     /**
 51      * @param args the command line arguments
 52      */
 53     public static void main(String[] args) {
 54
 55         if (args.length < 1) {
 56             System.err.print("You must provide at least a file name with path!");
 57             logger.log(Level.WARNING, "You must provide at least a file name with path");
 58             System.exit(0);
 59         }
 60
 61         RandomAccessFile raf = null;
 62
 63         try {
 64             raf = new RandomAccessFile(args[0], "rw");
 65         } catch (FileNotFoundException e) {
 66             logger.log(Level.SEVERE, null, e);
 67             // Error, set return to 1, and exit 
 68             System.exit(1);
 69         }
 70
 71         for (int i = 1; i < args.length; i++) {
 72             try {
 73                 raf.seek(raf.length());
 74                 raf.writeBytes(args[i] + "\n");
 75             } catch (IOException e) {
 76                 logger.log(Level.SEVERE, null, e);
 77             }
 78         }
 79
 80         try {
 81             raf.close();
 82         } catch (IOException e) {
 83             logger.log(Level.SEVERE, null, e);
 84         }
 85
 86         RandomAccessFileExample.readRAF(args[0]);
 87
 88         try {
 89             raf = new RandomAccessFile(args[0], "rw");
 90
 91             /* If you call seek() before you read, it will not work
 92              * as expected. The read operation will move the cursor
 93              * to the end of the read method.
 94              */
 95             //raf.seek(0); 
 96
 97             byte[] b = new byte[(int) raf.length()];
 98             raf.read(b);
 99
100             /* Here we place the seek() method to append to
101              * start writing at the beginning of the file.
102              */
103             raf.seek(0);
104             raf.writeBytes(CLASSNAME + "\n");
105
106             // Append the original content of the file.
107             raf.write(b);
108             raf.close();
109         } catch (IOException ex) {
110             logger.log(Level.SEVERE, null, ex);
111         }
112         RandomAccessFileExample.readRAF(args[0]);
113     }
114
115     public static void readRAF(String fileName) {
116         try {
117             RandomAccessFile raf = new RandomAccessFile(fileName, "r");
118             String line = null;
119             while ((line = raf.readLine()) != null) {
120                 System.out.println(line);
121                 logger.log(Level.INFO, line);
122             }
123         } catch (FileNotFoundException ex) {
124             logger.log(Level.SEVERE, null, ex);
125         } catch (IOException ex) {
126             logger.log(Level.SEVERE, null, ex);
127         }
128     }
129 }

UPDATED 12/29/2009
The Netbeans project is here: RandomAccessFile.zip

Here is an example of how to delete a String value from the file.

public static void deleteRAF(String value, String fileName) {
        try {
            RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
            long position = 0;
            String line = null;
            while ((line = raf.readLine()) != null) {
                System.out.println("line::line.length()::position::getFilePointer()");
                System.out.println(line + "::" + line.length() + "::" + position + "::" + raf.getFilePointer());
                logger.log(Level.INFO, line);

                if (line.equals(value)) {
                    //Create a byte[] to contain the remainder of the file.
                    byte[] remainingBytes = new byte[(int) (raf.length() - raf.getFilePointer())];
                    System.out.println("Remaining byte information::" + new String(remainingBytes));
                    raf.read(remainingBytes);
                    //Truncate the file to the position of where we deleted the information.
                    raf.getChannel().truncate(position);
                    System.out.println("Moving to beginning of line..." + position);
                    raf.seek(position);
                    raf.write(remainingBytes);
                    return;
                }
                position += raf.getFilePointer();
            }
        } catch (FileNotFoundException ex) {
            logger.log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            logger.log(Level.SEVERE, null, ex);
        }
    }

Friday, June 27, 2008

Putting the Current Directory in the CLASSPATH

Someone from our users group posed a good question. Should you put the current directory in the CLASSPATH? Does it represent any security issues like on UNIX?

Here is the answer...depends, but it is generally a bad idea. Here is an example. I created a class called TestCase. It calls another class called ClassA in a jar file called ExampleJar.jar. I put another class called ClassA in the current directory and set the CLASSPATH as a passed parameter

java -classpath .:./lib/ExampleJar.jar TestCase
Here are the classes:


1 public class TestCase {
2
3 public TestCase() {
4 }
5
6 public static void main(String[] args) {
7 ClassA a = new ClassA();
8 a.print();
9 }
10 }


1 public class ClassA {
2
3 public void print() {
4 System.out.println("I am ClassA in a jar.");
5 }
6 }


1 public class ClassA {
2
3 // Bad apple!!!
4 public void print() {
5 System.out.println("I am ClassA in the wild...");
6 }
7 }


The question becomes which one of the ClassA files gets called? The legitimate one, or the bad apple?

[sundev:Desktop:root]#java -classpath .:lib/ExampleJar.jar TestCase
I am ClassA in the wild...
If I reverse the order to java -classpath lib/ExampleJar.jar:. TestCase

I get the expected result:

[sundev:Desktop:root]#java -classpath lib/ExampleJar.jar:. TestCase
I am ClassA in a jar.
The Classloader finds the first instance of the class which matches the appropriate signature and loads it. Subsequent classes of the same name and signature are not loaded.

Why does it matter?

The inclusion of the current directory into the CLASSPATH represents a potential security risk, also it may produce unexpected results from similarly named classes. The second item may be a bit more contrived in general terms, i.e. com.abc.ClassA and com.cba.ClassA are called ClassA, but are in different packages. This will not represent a problem.

The security issue can be real. A lot of programs that do installs on Windows specifically, add the CLASSPATH variable to the Windows environment and put the . (period) first. I checked my installation and found it to be the case. I would not knowingly put it there myself. Also I checked a couple of tutorials which suggest that you should do it for convenience. That piece is quickly forgotten 200 pages ago.

ADDENDUM:

Java 6 SE (J6SE) has added some additional enhancements around classpath. You can use the * (asterisk) wildcard to include all files in the classpath:

java -cp "*"; TestCase (Windows)
java -cp '*' TestCase (Unix/OS X)

Mark Reinhold has a blog entry entitled Class-Path Wildcards in Mustang which details it.

Tuesday, June 24, 2008

Sample QuartzScheduler Job connecting to HSQLDB

I was cleaning up my system and looking at code samples from over the years. I came across an example Job using the Quartz Scheduler to connect to an HSQLDB database and reading the information about the session. I thought I would update it a little and post it.

Requirements:

You must have an HSQLDB database running in server mode.


package com.bluelotussoftware.quartz.example;

/*
* HSQLJob.java
*
*/

/*
* Copyright (C) 2008 Blue Lotus Software. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED "AS IS," WITHOUT A WARRANTY OF ANY KIND.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* BLUE LOTUS SOFTWARE, LLC AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES OR LIABILITIES
* SUFFERED BY LICENSEE AS A RESULT OF OR RELATING TO USE, MODIFICATION
* OR DISTRIBUTION OF THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* BLUE LOTUS SOFTWARE, LLC OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
* CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED
* AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE
* OF OR INABILITY TO USE SOFTWARE, EVEN IF BLUE LOTUS SOFTWARE, LLC
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

/*
* Copyright 2008 John Yeary
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/**
*
* @author John Yeary
* @version 1.0
*/
public class HSQLJob implements Job {

Connection con;
Statement s;
ResultSet rs;
ResultSetMetaData rsmd;

/** Creates a new instance of HSQLJob */
public HSQLJob() {
}

public void execute(JobExecutionContext context)
throws JobExecutionException {

try {
Class.forName("org.hsqldb.jdbcDriver");
} catch (Exception e) {
System.err.println("ERROR: failed to load HSQLDB JDBC driver.");
e.printStackTrace(System.err);
throw new JobExecutionException("Job Could not continue bacause driver failed to load");
}

System.out.println("Connecting to database...");

try {
// This may need to be changed to match the actual database name
con = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/glassfish", "sa", "");
} catch (SQLException e) {
throw new JobExecutionException("Failed to connect to HSQLDB Server");
}

try {
String sql = "SELECT * FROM INFORMATION_SCHEMA.SYSTEM_SESSIONINFO";
s = con.createStatement();
rs = s.executeQuery(sql);
rsmd = rs.getMetaData();
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
System.out.print(rsmd.getColumnName(i) + "\t");
}
System.out.println();
while (rs.next()) {
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
System.out.print(rs.getString(i) + "\t");
}
System.out.println();
}

// Clean up the connection
rs.close();
s.close();
con.close();

} catch (SQLException e) {
System.err.println(e.getMessage());
while (e.getNextException() != null) {
System.err.println(e.getMessage());
}
}
}
}




package com.bluelotussoftware.quartz.example;

/*
* QrtzScheduler.java
*
*/

/*
* Copyright (C) 2008 Blue Lotus Software. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED "AS IS," WITHOUT A WARRANTY OF ANY KIND.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* BLUE LOTUS SOFTWARE, LLC AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES OR LIABILITIES
* SUFFERED BY LICENSEE AS A RESULT OF OR RELATING TO USE, MODIFICATION
* OR DISTRIBUTION OF THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* BLUE LOTUS SOFTWARE, LLC OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
* CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED
* AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE
* OF OR INABILITY TO USE SOFTWARE, EVEN IF BLUE LOTUS SOFTWARE, LLC
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

/*
* Copyright 2008 John Yeary
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.text.ParseException;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

public class QrtzScheduler {

public static void main(String[] args) {
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler;
try {
scheduler = schedulerFactory.getScheduler();
scheduler.start();

JobDetail job = new JobDetail("hsqldb_example",
scheduler.DEFAULT_GROUP, HSQLJob.class);
CronTrigger cron = new CronTrigger("cron",
scheduler.DEFAULT_GROUP, "0/10 * * * * ?");
scheduler.scheduleJob(job, cron);

} catch (SchedulerException e) {
} catch (ParseException e) {
}
}
}



The Netbeans 6.1 project is located here: HSQLDBQuartzExample.zip

Sunday, June 22, 2008

The Tipping Point : How Little Things Can Make A Big Difference

I just finished reading the book The Tipping Point by Malcolm Gladwell. On the surface this does not seem to be a book on programming, and it is not.

I really liked the book because it assembled a number of political and social theories into a readable and digestible items. The Broken Windows Theory, which makes hypothesized that if a vacant building gets a broken window, you should fix it as soon as possible. The consequences of not-fixing it result in people assuming that no one really cares. The result is the rest of the windows getting broken. If you fix the window, then it is likely that no further damage will be done. This policy was implemented in New York in the 1990s. The result was a dramatic reduction in crime, and vandalism. This is the case of making a small change which results in further downstream effects. The explanation in the book is insightful and makes these theories easy to understand.

How does it relate to software and technology? It covers a methodology for making trends and social behaviors "stick". The ideas covered in the book speak in terms of epidemics. Those who understand viral expansion loops (viral marketing) will be able to understand the book and its underlying premises. If you are looking for some material on viral expansion loops (Viral Marketing), there is a really good one on Fast Company which is very well done. Fast Company had a cover article for May 2008 on CEO Gina Bianchini of Ning. They mention the use of viral expansion to attempt to grow Ning into a social powerhouse.

The book details items on how to make things stick, and how to spread the word about something. My stickiness factor is how to make social networks stick. For example, why is Facebook becoming more popular than MySpace. Why do people use LinkedIn? What benefits are there to blogging. This book can provide a wealth of information into social and environmental factors which make software and technologies popular.

The book is a real quick read, and I would recommend it with 4/5 stars.

Wednesday, June 18, 2008

Apache Derby (JavaDB) INSERT Statement with IDENTITY

If you are trying to insert values into a table which has an identity column, the documentation is not very clear. If I create a table in an Apache Derby (JavaDB) database which has a primary key which is generated always, the syntax for doing a query based insert is a little different.

Here is the table:
CREATE TABLE FAMILY (
ID INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
DESCRIPTION VARCHAR(50) NOT NULL
)
Now if I want to insert values from another table here is the query I used:
INSERT INTO FAMILY (DESCRIPTION) ( SELECT DISTINCT FAMILY FROM EQUIPMENT_GROUP WHERE FAMILY IS NOT NULL)
Please note that I did not put anything into the ID column. If I try to specify a value, it will result in an exception
Exception: Attempt to modify an identity column 'ID'.
Since the column has been marked as GENERATED ALWAYS, it handles incrementing the key and assigning it.

Monday, June 16, 2008

Configuring Apache 2 HTTP Server on Solaris 10

How do you configure Apache 2 HTTP Server to run automatically on Solaris 10 using rc init scripts.

Log into the Solaris box as root, or su root.
Go to the /etc/init.d directory.
Copy the apache startup script to apache2
cp apache apache2

Change the group to sys
chgrp sys apache2
Next change the flags on the file to execute
chmod u+x apache2
Open the apache2 file with your favorite editor and modify the following lines:

APACHE_HOME=/usr/apache
CONF_FILE=/etc/apache/httpd.conf
RUNDIR=/var/run/apache
PIDFILE=${RUNDIR}/httpd.pid

as follows:

APACHE_HOME=/usr/apache2
CONF_FILE=/etc/apache2/httpd.conf
RUNDIR=/var/run/apache2
PIDFILE=${RUNDIR}/httpd.pid

Check to make sure you have a valid httpd.conf file located in /etc/apache2. You can copy the httpd.conf-example file to httpd.conf. This will create a basic httpd.conf file.

Next go to the /etc/init.d directory and try executing the apache2 file. You should see something like this:

[dev1:init.d:root]#./apache2 start
httpd starting.
You can check your configuration by using a browser to check it.

Next you will want to configure it to start/stop at the various runlevels.

Go to /etc/rc0.d and add the following:
ln -s ../init.d/apache2 K17apache2
Go to /etc/rc1.d and add the following:
ln -s ../init.d/apache2 K17apache2
Go to /etc/rc3.d and add the following:
ln -s ../init.d/apache2 S51apache2
Go to /etc/rcS.d and add the following:
ln -s ../init.d/apache2 K17apache2

This will complete the configuration for your server. Next time you change run levels, or reboot, the Apache 2 HTTP Server will restart as you expect.

Addendum:

Zaphod commented on my page about using Solaris SMF. This is truly easier.

1. Check to make sure you have a valid httpd.conf file located in /etc/apache2. You can copy the httpd.conf-example file to httpd.conf. This will create a basic httpd.conf file.

2. Execute svcadm -v enable -rs apache2

3. You are now running on Apache2 on SMF.

Saturday, June 14, 2008

Disabling JavaServer Pages (JSP) Expression Language (EL) and Scripting

I was looking at some JSP pages which contained a bunch of JSP script and JSP Expression Languange (EL) tags. The question was how to disable either both, EL, or scripting. Here is the solution.

You need to add, or change the configuration in your web.xml file. There are two ways configuration parameters which control scripting and EL.

<jsp-config>
<!-- Set to true to disable JSP scriptiing syntax -->
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>false</scripting-invalid>
</jsp-property-group>
<!-- Set to true to disable Expression Language (EL) syntax -->
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>false</el-ignored>
</jsp-property-group>
</jsp-config>


The lines above control how the page is translated. They are both currently set to false.

Here is an example of a jsp page with both scripting and EL.


1 <%@page contentType="text/html"%>
2 <%@page pageEncoding="UTF-8"%>
3 <%@ page import="java.util.Date" %>
4
5 <jsp:useBean id="now" scope="request" class="java.util.Date"/>
6
7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
8 "http://www.w3.org/TR/html4/loose.dtd">
9 <html>
10 <head>
11 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
12 <title>JSP Configuration</title>
13 </head>
14 <body>
15 <h1>JSP Configuration</h1>
16 <p>
17 Browser MIME types: ${header.accept}
18 </p>
19 <p>
20 Browser Compression: ${header["accept-encoding"]}
21 </p>
22 <p>
23 The context-path initParam is: ${initParam.customerServiceEmail}
24 </p>
25
26 <p>
27 HTTP Request Method: ${pageContext.request.method}<br>
28 HTTP Response Type: ${pageContext.response.contentType}<br>
29 HTTP Session ID: ${pageContext.session.id}<br>
30 HTTP Context Path: ${pageContext.servletContext.contextPath}
31 </p>
32 <p>
33 Date (script): <%= new Date()%><br>
34 Date(EL): ${now}
35 </p>
36 </body>
37 </html>
38


The resulting output looks like this:



After setting <scripting-invalid>true</scripting-invalid> The page will
throw an exception is there are any JSP scripting elements on the page.



I went back and set the value back to false and set the <el-ignored>false</el-ignored>
This causes the container to treat the EL syntax as literal text.
The result is what you would expect. The only values diaplayed are JSP script.



The question is why would you want to go through the effort... If you were doing work on JSP pages
prior to JSP 2.0, you may have used some syntax similar to EL which you may not want
to have translated.

Turning off scripting forces the developer to use Java Standard Tag Libraries (JSTL)
and Expression Language (EL). This ensures a cleaner separation of code from
presentation in the MVC paradigm.

Netbeans 6.1 Javadoc Auto Comments

At the Greenville Java Users Group (GreenJUG) meeting the other night, the topic of auto comments for Javadocs was brought up. In Netbeans 6.1, if you enter a method and then starting typing /** / on the method it will create Javadoc comments for you. For example,

private String fx(String x) {
return x;
}


Next add a Javadoc comment /** */ and you will end up with something like this:

/**
*
* @param x
* @return
*/
private String fx(String x) {
return x;
}


This is a great start to your comments.

There is a plugin in the Netbeans Development Center called Javadoc Analyzer. Download and install this plugin. It will provide you with some cool additional functionality.

In this screenshot I have created a servlet using the Netbean defaults which include some default Javadoc comments. I then ran the Analyze Javadoc menu item under Source. You can see it found a number missing tags including some on the visible text.



I then instructed it to Fix Selected



This resulted in the comments being added and marked as completed.

Saturday, June 07, 2008

New Blog Template

I decided to change the look and feel of my blog. I went with a more minimalist design. I wanted to make sure that I could add content more easily, and that the constraints of the template would not interfere with the content.

I am hoping to add more content and links to the site. I have a couple of tutorials, and book reviews I am working on right now.