BibleGateway.com Verse Of The Day

Friday, February 23, 2007

Apache "Maintenance" Pages Using mod_rewrite

Just found out about the power of mod_rewrite in the Apache web server. To enable a system wide "maintenance" page (system not available type thing) you need enter only 2 lines of code in the httpd.conf file and restart apache. This is so simple, it kind of baffles me why this example wasn't mentioned in the 2 links I used to figure it out.

The pattern matches for everything except maintenance.html and sends the request to maintenance.html. That is important, because at first I tried to redirect all requests by matching on ^/(.*) but that got into an endless loop, since it would redirect request to maint page which redirected to the maint page which redirected to, well you get the idea.

Here is my rule:
RewriteEngine On
#RewriteRule !^/maintenance.html$ /maintenance.html [R,L]


Save file, cd ../bin and sudo ./apachectl restart and presto! All requests go to maintenance.html instead of the intended destination. Comment out those 2 lines, restart, and all normal.

Links of interest:

FOLLOWUP - 3/29
My maintenance redirect wasn't working for requests already coming in over SSL. I had to add the rule to the secure virtual host config section as well for it to work. Special thanks to "shimmyshack" on the alt.apache.configuration newsgroup for pointing me in the right direction.

Thursday, February 22, 2007

2007 DST Issues And Java

This daylight savings time (DST) issue is a pain in my buttI didn't need right now. We still have legacy applications running on JRE 1.2.2, and since it is Silverstream 3.5, changing anything out from under will destroy the world and it will not run right, if at all.

Links to Sun's FAQ is at http://java.sun.com/developer/technicalArticles/Intl/USDST_Faq.html
Of notable interest here is this little tidbit of crap:
  1. Do my operating system's timezone patches fix the Java platform's timezone data?
    • No. The Java SE platform's timezone data is not read from the local or host operating system.
    • The Java SE platform maintains a private repository of timezone data in locally installed files (.../jre/lib/zi) as part of the Java Runtime Environement (JRE) software.
      • Applying whatever operating system timezone patches (for example Solaris OS, Linux, Windows) will have no effect on the accuracy of the Java SE platform's timezone data.

Well isn't that lovely? Java doesn't rely on the underlying OS to get timezone info. I'm sure there's a "good" reason, but it seems like pointless redundancy to me. Why set it up on the OS if the JVM doesn't use it? Sure there is probably some backward OS that has no concept of timezones, so Java abstracts everything to a point of uselessness just like Swing UI's.

If installing or updating new JRE is not an option (say, in production where the app server and all the apps haven't been tested on newer JRE's) The JRE updater tool is found at http://java.sun.com/developer/technicalArticles/Intl/USDST_Faq.html -- not sure how reliable ot stable that thing is, but we'll find out in our dev and test environments soon enough.

There is a brief discussion on the Jboss forums at http://jboss.org/index.html?module=bb&op=viewtopic&t=98682 as well. Or for Websphere http://www-1.ibm.com/support/docview.wss?rs=180&context=SSEQTP&dc=D600&uid=swg21219396#actions.

Venison And Mushrooms In Gravy

This is a simple "recipe" we did tonight that was extremely good -- very tender meat and great flavor. We didn't really have a recipe, so I don't know what to call it (Bambi swimming in gravy?)

1 lb. venison, cut in 1" cubes
2 cups mushrooms, sliced or cubed
Beef gravy, mix or pre-made.
Flour
Salt
Pepper
Garlic Powder

  1. Heat up a cast iron skillet with a little bit of oil.
  2. Mix the salt, pepper, garlic powder into some flour on a plate or in a plastic bag.
  3. Dredge meat cubes in the seasoned flour and brown each side in the pan. Don't worry about cooking all the way through, just searin the juices. Once browned, remove the meat from the skilet and set aside.
  4. Sautee the mushrooms in the same pan, using a little oil or butter as necessary to soften them up. Remove and set aside with the meat.
  5. Pour the gravy (or mix up the gravy mix according to directions, we used 3 packages but 2 would have been fine) into the skillet.
  6. Put the meat and mushrooms back into the skillet, lower heat, cover, and simmer for about 30 minutes or so, until meat is tender and fully cooked.
We dumped this over white rice and it was delicious.

Next time I would probably try adding some sauteed onions in with the mushrooms as well. There's really no reason why you couldn't substitute some other meat for the venison, e.g. elk, caribou, bear, rabbit, squirrel, or even beef.

Wednesday, February 14, 2007

"Peterbilt" Dodge Ram

This thing is sweet. He must have spent a lot of cash and time on this custom project. I only looked at the pictures so far, but I plan on going back to read it later. He started with a Ram 3500 and put a Peterbilt cab on it, truck bed off an old Chevy, 40" Mickey Thompson's, etc. Must be seen to be believed....

http://www.autoblog.com/2006/09/13/when-a-dodge-ram-just-isnt-sufficiently-truck-like

Server Printing Using Java Print Service

The first and most obvious thing you will notice about the Java Print Service (JPS) API's is that it is pretty much geared toward client side printing. For example, to look up print services you use javax.print.PrintServiceLookup, which has methods to lookup the default print service, lookup all the print services that match the given AttributeSets and/or DocFlavor's. That all makes sense if you are building a print dialog with the default printer selected already, and a list of all the other printers defined on the system, to allow the user to choose one.

On the server, however, printing is just one more stop in a process flow. It has to just happen automatically, which means you have a specific printer in mind for the stuff to go to. Notice on the PrintServiceLookup class, there is no method to get a specific named printer service. In my mind, that is a deficiency, but one that is easily rectified.

Here is the code I use to lookup a named printer service. The name is kept in a properties file that gets bound to JNDI, or it could be kept in a database, etc. Basically you pass in null for the DocFlavor and AttributeSet to get all print services on the machine. Then loop through those looking for a match, and return the matching service, or throw an Exception.



import javax.print.*;

...

public PrintService getNamedPrintService(String prnName)
throws Exception
{
PrintService[] prnSvcs;
PrintService prnSvc = null;

// get all print services for this machine
prnSvcs = PrintServiceLookup.lookupPrintServices(null, null);

if (prnSvcs.length > 0)
{
int ii = 0;
while ( ii < prnSvcs.length )
{
log.debug("Named Printer found: "+prnSvcs[ii].getName());
if (prnSvcs[ii].getName().equalsIgnoreCase(prnName))
{
prnSvc = prnSvcs[ii];
log.debug("Named Printer selected: "+prnSvcs[ii].getName()+"*");
break;
}
ii++;
}
}

if (prnSvc == null)
{
throw new Exception("Printer " + prnName + " was not found on this system.");
}

return prnSvc;
}

Parsing Fixed-Length Positional Text Data

I recently had to parse out positional (fixed-length field) data, and I really didn't want to write some ugly hard-coded parser that would break every time a field changed length or a new field was added.

I also didn't want to write some overly complicated abomination with XML configuration files and AbstractFactories and visitor patterns and so on (you know, like the Apache guys would have done.)

Instead I chose to use some of the new features of JDK 5 -- like enums and the enhanced for loop. I create an enum like the one show below.


public enum GetTransactionFields
{
ADDR_ID (10, Justification.LEFT_SPACEFILLED),
ADDRESS (70, Justification.LEFT_SPACEFILLED),
TYPE_CODE (1, Justification.NONE),
ACCOUNT_INFO_IND (1, Justification.NONE),
RECEIVE_OFFERS_IND (1, Justification.NONE),
THIRD_PARTY_IND (1, Justification.NONE),
CUSTOMER_EMAIL_STATUS (1, Justification.NONE),
WIRELESS_CARRIER (4, Justification.NONE),
INVALID_IND (1, Justification.NONE),
SOURCE_CODE (1, Justification.NONE),
SYSTEM_CODE (1, Justification.NONE),
LAST_UPDATE (8, Justification.NONE),
;

private int fieldSize;
private Justification justification;

/** Private constructor */
private GetTransactionFields(int fieldSize, Justification justification)
{
this.fieldSize = fieldSize;
this.justification = justification;
}

/**
* @return Returns the justification.
*/
public Justification getJustification()
{
return justification;
}

/**
* @return Returns the fieldSize.
*/
public int getFieldSize()
{
return fieldSize;
}
}


Now, to add a new field, I simply insert it in the right position, with it's fixed length and the justification (if you only get 10 characters in a 20 character field, are they left or right justified? In this case Justification is an enum as well, but I ended up not needing to use it)

If a field size changes, you only need to change the size here. Your parser code does not need to know or care. That parsing code is extremely simple. An example is shown below. This example just prints the field name (from the enum) and the value that was parsed out.

In my real application, I created an XML document using the enum names as the XML nodes, and the values were the parsed values. This way, the data was more flexible to work with, as I could use XSLT to show the data nicely formatted on a JSP log viewer, and use another XSLT to transform it into the format needed by the backend web services.


private void parseGetRecord(String record)
{
int posn = 0;
int endIdx = 0;
for (GetTransactionFields f: GetTransactionFields.values())
{
endIdx = posn + f.getFieldSize();
System.out.println("Parsing field " + f.toString() +", value = " + record.substring(posn, endIdx)));
posn = endIdx;
}
}


And that's all there is to it. An enum and a for loop. Simple, elegant, and best of all, maintainable even by drooling neanderthal programmers.

Reading a Text File Line By Line

Sometimes I need to read a text file line by line from Java code. Whether it's reading transactions to blast onto an MQ queue, or parsing out CSV files, the actual reading of the file remains the same. But it's something that I always have to look up an example for, because I don't work with all the streams, readers, and writers classes often enough to memorize.

Here's the simplest running example, basically a crappy implementation of the the Unix "cat" command (read a file and spit it out to the console, line by line). To get it to do something useful, replace the System.out.println with something more useful, like putting to a queue, or running the line through a CSV parser, or running a SQL query, etc.



import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class UnixCat
{
public void cat(String filename) throws IOException
{
BufferedReader is = new BufferedReader(new FileReader(filename));

String line = "";
while (line != null)
{
line = is.readLine();
System.out.println(line);
}
is.close();
}

public static void main(String[] args)
{
UnixCat uc = new UnixCat();

// Assume args is a list of filenames
for (int ii = 0; ii < args.length; ii++)
{
try
{
uc.cat(args[ii]);
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
}
}


Tuesday, February 13, 2007

Ram HEMI: First Shock

I ended up buying that Ram last week (http://redneckprogrammer.blogspot.com/2007/02/is-this-truck.html
), and I have to say it's awesome. It's a 2003 Ram 1500 SLT Quad Cab 4x4 with short bed and the 5.7 liter 345 HEMI V8. It hauls lots of serious ass. It's kind of hard to open her up with all the snow and ice we've had, but you can feel it growling under that big bulging RAM hood. The kids love and and always aks to ride in Daddy's truck.

I filled it up late last week to the tune of $50, then filled it up again last night. I did a little basic math and found that I got a little (very little) over 13 miles per gallon mileage. It was a little bit of a shock to fill that 26 gallon tank, and a bit of a shock to get 13 mpg, but it really can't be too much worse than the Jeep with 4.11 gears, 33" tires, and the aerodynamic qualities of a brick. I don't know for sure because I never actually calculated what the Jeep got. I figured I just didn't care enough to run the numbers. Anyone who drives a lifted and modified Jeep is not in it for the economic benefits. Same goes for driving a full size truck with a big V8.

The truck has all the goodies, towing package with the hidden hitch, trailer wiring, trailer brake controller, leather seats, overhead console, bed liner, "Infinity premium sound" system with the CD and cassette, fold out flat cargo deck in back seats, with storage under that, heated side mirrors, power locks/windows/driver's seat, auto transmission, etc.

Monday, February 12, 2007

Tonneau Covers

I'm looking to get a tonneau cover for the new Dodge Ram this spring. My father has one for his Dakota that attached very similar to the soft top on a Jeep. The problem is when it gets cold the material gets stiff and shrinks a bit. If you get it off, you'll never get it back on, as we found out when we were packing for our bear hunting trip last November. Lund and a couple other companies make a cover with the bows and frame built right in, so you just clamp it down to the bed rails. It folds up in 3 sections, and installs in minutes no matter what the weather.

The Lund is the Lund Genesis Tri Fold, and it's amazing how much of a range exists in pricing. At the cheapest, I have found Amazon.com has it for $282.74 with free shipping, and as high was 423.95 at Auto Parts Warehouse, with free shipping (gee, thanks, charge me and extra $140 but give me free shipping).

I was kind of amazed Amazon.com had it at all, let alone them being the cheapest by far. Remember when they sold books? And maybe CD's and movies? Now they are like the Super Walmart of the internet world.

Price list for Lund Genesis Tri Fold model 95064 for Dodge Ram 1500 Quad Cab short bed (6'3")
  • Summit Racing - $329.95
  • JEGS - didn't have it
  • Truck Addons.com - $330.99, free shipping
  • Truck Stuff USA - 369.99
  • JC Whitney - $359.99
  • Auto Parts Warehouse - $423.95, free shipping
  • Amazon.com - $282.74, free shipping

Saturday, February 03, 2007

Apple Picking Fall 2006

This past fall we went apple picking at Morgan Farms out here in 315 land. Here are a few pictures.

Daddy And Taryn
daddy and taryn
Mommy and Raina
mommy and raina

Pix From The Cabin (Last Fall)

Just going through some pictures on my hard drive. Here are a few from the cabin last fall.

Grammy and the girls coming back from a walk


Taryn, Teddie, and Charlie sleeping together. I think Charlie liked being able to sleep with Taryn, where she normally would have been sleeping in a brib at home.

Thursday, February 01, 2007

Winter Warmth

One of my favorite winter time recipes...

1. Fill a rocks glass with ice
2. Fill with bourbon
3. Enjoy responsibly.