Effective Java Collections

I thought this article, Effective Java Collections, was excellent.  Here is the summary of the article.

  1. Use the isEmpty() method of the collection.
  2. Avoid returning null to mean an empty collection.
  3. Create an empty collection using Collections.empty***() methods.
  4. Iterate through collections using the foreach form when possible.
  5. Use the proper collection, Collection, Map, Set, List.
  6. The left side is always an interface!  (So is the return type of methods.)
  7. If you’re explicitly casting, chances are something is wrong. Use generics.

Microsoft Office 2008 update 12.1.0 will not install

I tried many times to install the Microsoft Office 2008 update 12.1.0 but each time it would hang.

Finally I found this forum thread about the exact same problem, Msi Wind Forums • View topic – Microsoft Office 2008 update 12.1.0 will not install.

This is how to get the update to install.

Should have an option to edit……thing is it’s to late because your forced quit. Run the installer again and when the installer hangs move the installer window to one side…the error window noted above should be directly behind the installer and thats why you missed it in the first place…the installer has halted (and appears hung) as the error window is awaiting a response from you…..but you dont see it. All you have to do is click the edit button on the error window and then installer will continue…thats it. You can close the error window and the installer will continue.

Trim White Space from JSP

Untitled | FlickrSometimes the resultant HTML from JSP files has too much white space.  This is because a lot of JSP logic will result in only a few lines of actual HTML code and the rest is white space.

One efficient way to get rid of white space is to add this configuration to your web.xml on Tomcat/JBoss as described in this article, Trim Spaces in your JSP’s HTML.

/jboss/jboss-eap-4.2/jboss-as/server/atg/deploy/jboss-web.deployer/conf/web.xml
OR
/jboss/jboss-eap-5.1/jboss-as/server/atg/deployers/jbossweb.deployer/web.xml

<servlet>
    <servlet-name>jsp</servlet-name>
    ...

    <init-param>
        <param-name>trimSpaces</param-name>
        <param-value>true</param-value>
    </init-param>

    ...
</servlet>


However this sometimes has undesired side-effects. For example this DSP:

<div class="foo">
  <dspel:valueof param="displayName" />
</div>


causes this undesired result:

<div class="foo"/>
  Frank Kim


The work around is to do this.

<dspel:getvalueof  var="displayName" param="displayName" />
<div  class="foo"><c:out  value="${displayName}"/></div>

Update 06-09-2010: The above problem might have been happening because we were running with a version of ATG that is for Servlet 2.3. When we run with a version of JBoss that runs with Servlet 2.4, e.g.  ATG 9.1 with JBoss EAP 4.2, we no longer see this problem.

There is another tip on removing white space in this JSP FAQ: Why I am getting extra whitespace in the output of my JSP?  In our code we had one file which included a bunch of tag libraries.  It originally looked like this.

<%/** Taglibs.jsp: include to pull in all taglibs */%>

<%@ taglib uri="/dspELTaglib" prefix="dspel" %>
<%@ taglib uri="/jstlCoreTaglib" prefix="c" %>
<%@ taglib uri="/struts-bean" prefix="bean" %>
<%@ taglib uri="/struts-tiles" prefix="tiles" %


When we changed it to this we saved about 5% in terms of page size in bytes.

<%@ taglib uri="/dspELTaglib" prefix="dspel"
%><%@ taglib uri="/jstlCoreTaglib" prefix="c"
%><%@ taglib uri="/struts-bean" prefix="bean"
%><%@ taglib uri="/struts-tiles" prefix="tiles" %>


You can use this tip with a DSP page and maintain indentation.

<dspel:page    ><dspel:droplet name="/betweengo/droplet/Foo"      ><dspel:oparam name="output"        >Name: <dspel:valueof param="name"      /></dspel:oparam    ></dspel:droplet
></dspel:page>

Turning off JSP access

To turn off JSP access in your JBoss or other favorite application server add this to your web.xml.

<!-- Restrict direct access to jsps -->
<security-constraint>
  <web-resource-collection>
    <web-resource-name>you_cant_touch_this</web-resource-name>
    <url-pattern>*.jsp</url-pattern>
  </web-resource-collection>
  <auth-constraint/>
</security-constraint>

To prevent Apache from sending JSP requests to JBoss add the following to your configuration.

## DISALLOW FROM REACHING JBOSS (security-related filter):
!/*.jsp=name_of_your_app
!/*.xml=name_of_your_app

Cygwin Bash Scripts and Java

Running Java scripts in Cygwin bash scripts becomes a little tricky because you want to treat most paths in Cygwin as normal UNIX paths but Java expects DOS paths.  Therefore to get around this you can use the mixed option for cygpath.

For example:

if [ -e /usr/bin/cygpath ] || [ -e /bin/cygpath ]
then
  export FOO=`cygpath --mixed "e:\work\betweengo/target/foo"`
else
  export FOO="e:\work\betweengo/target/foo"
fi

The result on Cygwin is that FOO will be set to “e:/work/betweengo/target/foo” which will work both in DOS and UNIX.

Sets cannot be used as property types

I create a JavaBean with a Set property because I wanted to enforce that there were only unique values in that Set.  However when I tried to use this JavaBean with a properties file, Nucleus complained it could not resolve the elements of the Set property.  When I changed the property to be a List or a String [] Nucleus had no problem.

Here is the properties file.

$class=com.betweengo.droplet.VerifyImages
$scope=request

# supported image dimensions
supportedImageDimensions=75x90,88x31,120x90

ATG Support pointed me to the Property Types subsection of the Using Nucleus
section of the ATG Programming Guide.  Specifically only these simple types are supported.  I am not sure why Set was excluded.

boolean
byte
char
short
int
long
float
double
java.lang.Boolean
java.lang.Byte
java.lang.Character
java.lang.Short
java.lang.Integer
java.lang.Long
java.lang.Float
java.lang.Double
java.lang.String
java.util.List
java.util.Map
java.util.Locale

Best Practices for Creating Tables

Recently our DBA recommended the following for creating tables.

  1. All constraints (primary keys, unique keys, foreign keys, etc….) should be declared outside of the CREATE TABLE …. statements, and instead done as ALTER TABLE statements.
  2. All tables must have table and column comments to provide information for the data dictionary/schema metadata.

Not Best Practice:

CREATE TABLE items (
  id   VARCHAR2(40) NOT NULL,
  type NUMBER(5)    NOT NULL,
  PRIMARY KEY (id)
);

Best Practice:

CREATE TABLE items (
  id   VARCHAR2(40) NOT NULL,
  type NUMBER(5)    NOT NULL
);
ALTER TABLE items ADD CONSTRAINT items_pk PRIMARY KEY (id);
COMMENT ON TABLE items IS 'repository items';
COMMENT ON COLUMN items.id IS 'primary key (repository id)';
COMMENT ON COLUMN items.type IS 'item type';

I asked the DBA why this is considered best practice and this is what he said.

The DBA’s put indexes into a different tablespace than the table itself for storage, admin, and somewhat performance reasons (NetApp spreads out the I/O so does not quite apply to Upromise environment).

If the PK is part of the table create statement, they have to break out the statement in order to put the PK into a different tablespace or different storage parameters than the table. Having the statements separate from the start makes things smoother.

– Jeff Janousek, Upromise DBA

Repository creating tables automatically

Recently we noticed while running some ATG unit tests that tables were being created by the ATG repository if they had not already been created by our SQL scripts.  This was a functionality that I was unaware of but apparently it is not unique, Hibernate does this too.  I could not find any documentation about this nor could I determine how to turn it off.

The ATG repository creates these tables using the repository definition and the defaults for column width and data type.  It does not seem to warn that it is creating these tables.