Wednesday, November 17, 2010

Railo - Java Timezone Issue

I reset the system time zone in Ubuntu and then restarted Railo, but railo didn't have the new timezone.

I didn't want to reboot the server, so I researched and scripted this work-around:

<cfset variables.tzobj = CreateObject("java", "java.util.TimeZone") />

<cfset loc.timeZone = variables.tzobj.getDefault()>
Before Reset: <cfoutput>#loc.timeZone#</cfoutput><br /><br />

<cfset variables.tzobj.setDefault("US/Pacific")>

<cfset loc.timeZone = variables.tzobj.getDefault()>
After Reset:<cfoutput>#loc.timeZone#</cfoutput>

I ran that one on the server and it's good to go forever. I'll reboot the server late tonight and confirm that java gets the correct system timezone, but this worked for an immediate solution without rebooting or restarting Railo.

UPDATE: The above resolved the java offset, but issues were discovered between Railo (java) and SQL Database dates. It was converting back and forth between UTC and PDT (Pacific Daylight Savings Time). It was a mess. In addition, upon reboot Java revered back to the incorrect timezone. I had to test a fresh reboot because it was bound to happen. Glad I did.

The final solution to fixing the Java incorrect timezone came from a forum thread which pointed me to this link:

From there I leaned that there is another timezone file in Ubuntu located /etc/timezone which has Etc/UTC inside. That's it.

Simply deleting the file, or renaming it to /etc/timezone_old, and then rebooting fixed the java timezone.

The Java timezone object above is not a good solution. As I stated, there remains timezone issues between Railo CFML (essentially the Java Engine) and any other systems, namely MySQL.

Many thanks to the communities and forums for posting solutions.

Whew!

Railo - CFChart - SOLVED Error: Probable fatal error:No fonts found

I built a new production server and launched the new site this morning. Everything ran great, except...

On one report page that I did not test before launch there was a small chart in the corner of the report. A <cfchart...> which was throwing this error: Probable fatal error:No fonts found.

After a quick search I discovered this is a font issue with OpenJDK which most people resolved by uninstalling OpenJDK and installing Sun's JDK.

I didn't want to do that. So I kept searching.


This error has two issues: 1) The fonts are not installed.  And/Or,  2) OpenJDK doesn't know where to find the fonts.

Tackle issue number 1 - get the fonts. This is a new server and trying to locate any of the fonts that others were installing came up blank.

sudo apt-get install libfreetype6 and restarting railo - didn't fix it anything.

sudo apt-get install dejavu* and restarting railo - didn't fix it.

I know those two commands installed a bunch of fonts, so I'm closer.

I kept researching and found these two articles which explained a lot more:

From the second link there I found the instructions to run a java command to register installed fonts in the java font properties.

sudo java -jar compilefontconfig.jar fontconfig.config fontconfig.bfc
 
but that command complained that it couldn't find fontconfig.config.

locate fontconfig.config showed it to be in /etc/java-6-openjdk/fontconfig.properties

I'm in /usr/lib/jvm/java-6-openjdk/jre/lib and the other file fontconfig.bfc is here, so I tried:

sudo java -jar compilefontconfig.jar /etc/java-6-openjdk/fontconfig.properties fontconfig.bfc

And that ran properly. No output, but no complaints.

Then I restarted railo and... IT WORKED! The CFChart displayed perfectly.


And that's a wrap!

Thursday, November 4, 2010

Railo and JAVA_HOME issues (exec: 40: -jar: not found)

I have read others getting the "exec: 40: -jar: not found" error even after having the JAVA_HOME variable set, but I have not experienced that issue until today.

To resolve this issue I discovered that manually setting JAVA_EXE along with JAVA_HOME in the ~/.bashrc file fixes the issue.

Like this:  (for my java installation on Ubuntu, yours may be different)

export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
export JAVA_EXE=$JAVA_HOME/bin/java

That's it. Then Railo worked like a charm.


Another wrap!

Wednesday, November 3, 2010

Making Apache talk to Railo

Follow these steps to make Apache talk to Railo [ubuntu]:

sudo -s  ## do everything as root
cd /opt
wget [stable railo ALL-OS WITHOUT JRE from http://www.getrailo.org/index.cfm/download/]
tar -zxvf railo-...-without-jre.tar.gz -C .   ## to unpack into the current directory
ln -s railo-..-resin-without-jre railo
/opt/railo/bin/httpd.sh start  ## to make sure it starts - leave it running
apt-get install apache2 apache2-threaded-dev openjdk-6-jre-headless build-essential automake  ## make sure all of these are installed
vim ~/.bashrc
add this to the bottom and save:  export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
. ~/,bashrc
that re-initialized the bash settings, do this to confirm:
cd /opt/railo/modules/c/src   ##certain directory names are expected here, make sym links to resolve this
ln -s apache2 resin
ln -s resin resinssl
cd /opt/railo
./configure --with-apxs=/usr/bin/apxs2
autoconfig  ## mine errored on make and asked me to run this first then make again
make
make install

Then in /etc/apache2/httpd.conf  comment out ALL of the caucho lines that were installed there
and place it inside the sites-available config file after the names and directories, before the log files:

LoadModule caucho_module /usr/lib/apache2/modules/mod_caucho.so
localhost 6800
CauchoConfigCacheDirectory /tmp
CauchoStatus yes



That's it. It's worked a number of times in a row for me on Ubuntu.

Thursday, October 14, 2010

Dynamically adding jQuery to header only if it hasn't been loaded

Some time ago I did some research on Javascript and some magical, lesser known features that modern javascript libraries leverage to their great advantage.

It's not really all that magical when you get right down to it, but it is really cool.

Take this for instance:

<script>
     (function(){
        if(typeof jQuery == 'undefined'){
            var headID = document.getElementsByTagName("head")[0];        
            var jsNode = document.createElement('script');
            jsNode.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js";
            headID.appendChild(jsNode);
        }
    })();
</script>


On a partial template that may or may not be included within another template, we don't want to load jQuery twice. The above script checks if jQuery exists, if not then it appends jQuery to the header.

Lets break it down. I live this part:  Javascript works within a framework of code blocks. They are encapsulated within parenthesis (). This serves for nothing else than to isolated it's workings from the code around it. a second set of parenthesis ()() makes the first set of parenthesis self-executing upon page load. This is completely independent of any <body onload=""> type of functionality and is executed inline upon being rendered by the browser. You can have multiple instances. They are executed linearly, synchronously (as far as I understand).

The reason for breaking up the word SCR'+'IPT is because this code is nested within an outer set of <script></script> tags and will end the outer set prematurely and break the page.

There, now I can always reference this post whenever I need to find this code snippet in the future.


That's a wrap.

CFHTTP directly to output

We store our files on S3. Before they are uploaded there we know the file content-type and store it in the database with the file name and other data.

Then out site links to the file. This was previously exposing the raw S3 link with key and signature to the user - which is ugly.


Yeah, ugly. But it was functional. Images would display in the browser and files of other content type would be prompted for download.

I wanted to change that but googling wasn't providing the answers.

I'm using the awesome Railo CFML server. There were some ACF examples, incomplete at best, which referenced "cfhttp.fileContent.toByteArray()", but that wasn't working in Railo.

After an hour of trial and lots of errors, I came up with this so-far-solidly working solution:

<cfhttp url="#variables.s3filelink#" getAsBinary="yes" method="get" />
<cfheader name="Content-Disposition" value="inline;filename=#variables.filename#" />
<cfcontent type="#variables.filetype#" reset="Yes" variable="cfhttp.filecontent">


This solution hides the external S3 link and preserves the view-in-browser for images and prompts for download on other file types.

Also, it was important for images that the user can right click on the displayed image and select to save the file locally to their machine. Using the cfheader line shown above and setting the filename=#variables.filename# attribute the original file name is prevserved when the user is prompted to download the file. I found without that setting the download file name was the name of my cfml template - which is bad because it looses the original file extision of .jpg or .pdf. Very important.


That's a wrap.

Wednesday, June 16, 2010

Detecting and Correcting IE8 in COMPATIBILITY MODE

This was a fascinating find today.

I have been upgrading an older site with some new HTML5 functionality. Not super-bleeding edge HTML5, but things that are common between Safari, Firefox, and IE8, oh yeah, and Opera.

Doing some server-side detecting on the users 'User-Agent' string we can check their browser version and block the site if they are not using a compatible browser. This debated practice will not be discussed here. Lets move on.

So, regarding this terrible monster Internet Explorer which appears to be heading in a good direction in version 8 and even better in the upcoming version 9, we get the user agent strings for the following browser versions 7 and 8:

IE7: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
IE8: "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)"

But wait, if IE8 is set to be in "Compatibility Mode" we get this:

IE8: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0)"

See that? We have the IE layout engine named "Trident" appearing but we are given the browser version 7.0. That's the give-away that the user has IE8 but is set viewing in "Compatibility Mode".

(More info on this Trident engine can be found here: http://en.wikipedia.org/wiki/Trident_%28layout_engine%29. It appears this has been the layout engine for IE since the beginning, but it has never been exposed in the User Agent string until IE Version 8.)

But many users who have IE8 have [accidentally?] set their browsers to be stuck in "Compatibility Mode". This makes an HTML5 site render as if it were in IE7.

This is terrible! The user has the browser we want them to have but have marked a setting that unless they change they will not get the user experience we want them to have.

But wait, then we learn from the Microsoft Website that we can overcome this end-user setting and force IE8 to render NOT in compatibility mode but properly in IE8 mode. http://msdn.microsoft.com/en-us/library/cc288325(VS.85).aspx about half way down under "Understanding Content Attribute Values" we are given this:

<meta http-equiv="X-UA-Compatible" content="IE=100" />

Now we have IE8 with compatibility mode ON and yet it views our content properly, over-riding the user setting. This only affects IE browsers.

That's fantastic! Now we can detect for IE version 8 or greater,  OR  IE Version 7 with Trident version 4 or greater. We can use this meta tag and we don't have to block the site or ask the user to change a browser setting.

The strange thing is, I had the IE8 compatibility "button" visible by the browser address bar, and when I add this meta tag the button disappears completely preventing me from toggling compatibility mode ON/OFF.  Good for viewing the site properly, but strange that a meta tag changes the menu mar arrangement on my computer. Oh. Microsoft...

And that's a wrap.

Thursday, March 25, 2010

Happy Applications = Better Touch Tool + 'Snap'

I've had the Apple Magic Mouse for some time. When I first played with it in the store it was completely underwhelming. I was sorely dissapointed in it's native functionality. No 'Magic' at all.

The real magic comes from a third party application called "Better Touch Tool". It allows fully customizable multi-finger clicks and gestures to do [almost] anything imaginable. It's truly "Magic" for the Magic Mouse.

What's even better is the "Magic" in "Better Touch Tool" is available to all, even those without the Magic mouse. It has custom gestures for the Touch Pad as well as many keyboard commands that have nothing to do with the touch pad nor magic mouse.

The greatest piece of magic from yesterday's update to this application is that it adds "Snap" capability touted by Windows 7. The Snap capability on the Mac allows the user to drag the top bar of a window to the edge of the screen and it will 'snap' to exactly half screen width and full screen height.

Here's why this is so magical for me. I use the Matrox TrippleHead2Go hardware which turns two (yes, 2 and possibly 3 smaller ones) external monitors into one virtual monitor so that I can have two 20" monitors next to my MacBook Pro. It's really nice. The one issue is that it is virtually "one" monitor 11" high and 36" wide. It can me a pain to maximize windows in each monitor every time I'm plugged in. Now, with the updated Better Touch Tool with 'Snap' it's a breeze. Drag the top bar of the window to the left edge, and it snaps to it's half (exactly one monitor or the duo) and drag another window to the right edge and it snaps to the right half. SWEETNESS!

That is all.  Carry on.