Friday, September 30, 2011

Root Cause

I've picked up a fun nickname at work.  Root Cause.   I take it all in fun because I have been the root cause of a few problems, but I cause far less problems than I fix.

Today at work someone sent me a quote.


For every effect there is a root cause. Find and address the root cause rather than try to fix the effect, as there is no end to the latter.
-- Author Unknown

It's almost like there is a quote about me now.  That's lots of fun.

Tuesday, March 22, 2011

Accessing Websphere Variables at runtime.

I'm using Redis and I had a security need to keep the production configuration values hidden.  However, I wanted to allow other developers to run against test with minimal configuration.

I decided that I wanted to be able to read the Webpshere Variables that are configured on the WAS server through code.

I started with some code I found on IBM's site to get the data, but added a simple null check to make it return null if the code is not running on a server.


I had to add a reference to com.ibm.jaxws.thinclient_7.0.0.jar (this was the recommended reference by RAD) this .jar is needed for the AdminService class.

A few quirks
1. if the server is not running (when unit tests run) you have to handle a default value, this method will return null.
2. If the property does not exist on the server it returns in ${propertyname}. 
3. Any changes to the values on the server require a restart before they can be used by the application.

I handled this with a properties file that will be used when running unit tests or on my local server, and the values from Websphere variables will only be used in production.  I structured it in a way that the production values take precedence over the test values.

ResourceBundle settings=ResourceBundle.getBundle("twitter");

// if the values are not set then this will return ${variablename}
String redisServer = expandVariable("REDIS_SERVER");
if (redisServer == null || redisServer.startsWith("${")) {
                redisServer = settings.getString("redis.server");
}

String redisPassword = expandVariable("REDIS_PASSWORD");
if( redisPassword == null || redisPassword.startsWith("${")) {
                redisPassword = settings.getString("redis.password");
}

String redisPort = expandVariable("REDIS_PORT");
if( redisPort == null || redisPort.startsWith("${")) {
                redisPort = settings.getString("redis.port");
}


I still recommend clearing out the test values when deploying to production, this will ensure that if the production property has not been set and the server restarted that the application is not accidentally pointing at test.  I'd rather have an error that a production application pointing at test.

Monday, November 29, 2010

if statement failure.

Looking at an if statement I noticed a problem.   This works, but is technically incorrect.

if( a == null || b==null) {
// do something
} else if( a!=null || b != null) {
// do something else
}

The intention here is really.
if( isSomeState(a,b) ) {
// do something
} else if( !isSomeState(a,b)) {
// do something else
}

which means ultimately it's looking for
(a == null || b==null)
and
!(a == null || b==null)
However !(a == null || b==null) translates into
a != null && b!=null

It happens to work by accident because if either are null the code will go into the if statement and never evaluate the else if portion, however, if the statement were to get more complex intentionally then it could cause all kinds of mistaken errors.

What if the code changed to be

if( a == null || b==null || c==null) {
// do something
} else if( a!=null || b != null) {
// do something else
}

only now the intention is 
if( isSomeState(a,b)  || c==null ) {
// do something
} else if( !isSomeState(a,b)) {
// do something else
}

What was previously be handled by the if statement is no longer handled, and the else if, will handle situations that it did not evaluate before, the something else will happen a lot more than it's supposed to.

When writing complex if statements and the else if is supposed to be the opposite state of the if, then refactor that logic into method and use the method and !method to ensure that the correct logic is used.

Monday, October 04, 2010

How to reliably set the width of an input box.

Input boxes are a pain to get the right length.  There are a few ways you can do it, but only one that is cross browser compatible.

The best way to limit the width is to use the display tag or css.

The css method would be to have a style
.width80 {
 width: 80px;
}


There is a tag that is also supported across browsers, the Size tag this is less reliable.

The size lets the browser know that this text box should big enough to hold 30 characters.   The different browsers interpret this differently.  They have their own internal math that they do and the fonts may be different across browsers, so using the size attribute to define the width of a text box may mean that on one screen the text box is too long and messes with the appearance of the screen that you want to design.

Many times I'm trying to align columns with more of a fixed width, using size to set the width of a text box causes me problems across browsers.  Keep this in mind as you style your own input boxes.

Tuesday, September 28, 2010

IE7 ghost text

This week we ran into an odd problem with Ghost text showing up in our application  Google turned up a lot of similar problems with no clear cause or solution,  I used the development tools to help me figure out a way to solve the problem.  The scenario that it appears to cause it is if there is a div that is floating, it has a width of 100%, and a margin, then the text inside of it may cause ghost text.   Oddly, the same html did not cause the same problem everywhere on the page.


This is setup like this.
PRODUCT DETAILS


Unfortunately, I’m not sure if that is the only thing required to cause this problem.   While I tried to fix the problem it went away with several different things. 
  • When I removed float: left, the ghost text disappeared.
  • When I set margin-left: 0px; the ghost text disappeared.
  • When I changed the structure to the following the ghost text disappeared.
    PRODUCT DETAILS

I went with the last option.  It kept the integrity of the rest of the CSS in place, and made the end result look the way that I wanted it to look.  I’ve seen lots of blog posts about the same problem.  Nobody, including Microsoft, seems to have a clear understanding of what the official cause is.  It only happened in some places in tye application and not in others, even though they were set up the exact same way.   For safety I changed them all to option 3.  IE7 had the problem, but IE8 did not.

A quick note on IE7 vs. IE8,  If you have IE8 installed, you can use the developer tools (F12) to change how the page displays and view it as if it were IE7.  I frequently do this while testing applications because IE7 and IE8 do not show everything the same way, sometimes you have to handle things a little bit differently.

Monday, September 27, 2010

jQuery UI Autocomplete extensions

Scott Gonzalez posted a blog post August 24th about some auto-complete extensions that he wrote.  

One of these is the ability to automatically select the item that is highlighted, so once it’s highlighted the user can hit enter, click it, or just tab off of the field and it will select that item.  There are also some other nice advanced features here, I encourage you to read this post.  http://blog.jqueryui.com/2010/08/extensible-autocomplete/

Saturday, September 25, 2010

jQuery UI 1.8.5 released

jQuery 1.8.5 was release September 17th  http://blog.jqueryui.com/2010/09/jquery-ui-1-8-5/
This is a bug fix release mostly, but it has one powerful new feature that I've been waiting for.  We now have more power over the buttons on the dialog.  We can set them to primary and secondary buttons, as well as disabled.  The styles of these buttons are built into the theme.  There is ui-priority-primary, ui-priority-secondary, and ui-state-disabled.

Also the text on the button is no longer limited to a string, we can now include html, so if we wanted to bold a single word on a multiword button we could have something like “Find account” 

Here’s an example of how to use the new functionality,  
el = $("
").dialog({
                buttons: [
                                {
                                                text: "a button 1",
                                                "class": "ui-priority-primary",
                                                id: "my-button-id-1",
                                                click: function() {
                                                                alert("button 1 clicked");
                                                }
                                },
                                {
                                                text: "a button 2",
                                                "class": "ui-priority-secondary",
                                                id: "my-button-id-2",
                                                click: function() {
                                                                alert("button 2 clicked");
                                                }
                                }
                ]
});