Java with a passion!
Java7
Java7
Mar 5th
How many times have you come across codes that use \n for newline representation. Newline representation varies across operating systems.
All the time we have been using “\n” to represent a newline sequence, we could actually use something more portable to represent a newline feed that is guaranteed to work across operating systems that Java runs on.
Conventional code:
log.debug(list.get(i).getName() + “\n”);
Piece of code that does the above using line.separator:
log.debug(list.get(i).getName() + System.getProperty(“line.separator”));
Advantage
Using line.separator guarantees platform compatibility for newline sequence. Java processes line.separator into the respective newline sequence representation of the operating system it is run on.
Quick glance of the difference in newline sequence representation between operating systems:
\n = CR (Carriage Return) // Used as a new line character in Unix
\r = LF (Line Feed) // Used as a new line character in Mac OS (Old Mac OS, not Mac OSX)
\n\r = CR + LF // Used as a new line character in Windows
Feb 14th
Okay it doesn’t have to be 8 environments or 3 databases.
And pardon me for using the term Database to refer to DBMS. (What it really should be called … read the book Relational Theory by CJ Date)
The Situation
In a typical scenario, you have multiple environments, for example, SIT, UAT, Pre-production, production and disaster recovery.
On top of that, you have have multiple databases in each environment, for example, Edwards Payroll database, Resource Planning database and Customer Relation Management database.
Rarely will you need to build an application that connects to so many environments and databases. But when you do need this, you can use the Decorator pattern to implement the requirement.
Why Inheritance Doesn’t Help
If you knew inheritance, this would have been an good situation to put into practice some OO concepts, however as you will soon see, using inheritance-only gives rise to class explosion as the number of classes increase with the number of environments and databases that you want to connect to.
Environments illustrated:
SIT, UAT, PPT and Production.
Databases illustrated:
ERP, Payroll, CRM, and Billing.
As you see from above, it is simply not feasible to maintain this complexity if using inheritance-only.
The Decorator Pattern
The Java I/O package is based on Decorator design pattern, at least from 1.0 through 6 (Technical name 1.6), including 1.4.2.
How you commonly construct IO objects is what the decorator is about, and you were probably wondering why the weird idiom.
BufferedReader stdin = new BufferedReader(new InputStreamReader(new InputStream());
(I am sorry my code format plugin is not working at writing, when i get it back (if i do … or if somebody can drop me a mail to help ><), i will change the font family for readability.)
This is how our implementation looks like.
To get a SIT environment Payroll connection:
(new Payroll(new SITEnvironment())).getSession()
To get a Production environment CRM connection:
(new CRM(new ProductionEnvironment())).getSession()
Reference
The chapter on Decorator pattern is available for download freely from OReilly.
Feb 6th
As you can see, JSF validation produces ugly validation messages.
Solution
To get rid of this, add a label to your input field.
(This solution does not override the default behavior of the JSF message bundle, i will discuss that in more details in a follow-up write up soon)
For example:
<p:inputText id=”hotelName” value=”#{editHotelBackingBean.hotel.name}” required=”true” label=”Hotel Name“>
Feb 5th
You had a recent change of Primefaces JSF 2 component library (2.2.1 to 3.0.0) and your JSFs don’t work anymore.
Primefaces no longer use the tag
xmlns:p=”http://primefaces.prime.com.tr/ui“
Starting 3.0.0, it is switched to using the tag
xmlns:p=”http://primefaces.org/ui“
Once you have the alias changed, the warning will go away.
Dec 29th
Source code / Eclipse project download
I came across SLF4J as having the hot feature of performance advantage from using parameterized message logging and disabled logging feature but it has failed to mention if not migrating to the use of other three overloaded methods will too give this performance gain.
For instance, the SLF4J API has the following four overloaded log methods for the DEBUG logging level.
debug(String msg)
debug(String format, Object arg) // parameterized message
debug(String format, Object arg1, Object arg2) // parameterized message
debug(String format, Object[] argArray) // parameterized message
Of the four overloaded DEBUG methods, only the second, third and forth are parameterized message methods.
The question in this case is, while the second, third and forth overloaded methods are assured to have disabled logging feature, is the first method? The website does not clearly state this and i decided to do a little test.
Test
The test is simple, having configured the logging level to INFO, i attempted to do a DEBUG logging on each of the four overloaded methods. And true to it, no logs were printed – because the logging level is INFO.
However, in the console output, i noticed that the line “If you see this it means your expression was evaluated
Cat” was however printed, even when the logging level was inappropriate for the log to print.
This means that for the first logger (that is not parameterized message logging), does not have the disabled logging feature. The expression (“Test” + cat) inside was evaluated.
Main Method
Animal cat = new Animal("Cat");
Animal dog = new Animal("Dog");
Animal elephant = new Animal("Elephant");
Animal zebra = new Animal("Zebra");
logger.debug("Test " + cat);
logger.debug("Test {}", dog);
logger.debug("Test {}, {}", elephant, elephant);
logger.debug("Test {}, {}, {}", new Animal[] { zebra, zebra, zebra });
Animal Class
class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public String toString() {
System.out.println("If you see this it means your expression was evaluated
" + name);
return "test";
}
}
log4j.properties
log4j.rootLogger=INFO, CA
Run output (INFO log level)
If you see this it means your expression was evaluated
Cat
Run output (DEBUG log level)
If you see this it means your expression was evaluated
Cat
0 [main] DEBUG com.singtel.test.slf4j.SimpleTest - Test test
If you see this it means your expression was evaluated
Dog
0 [main] DEBUG com.singtel.test.slf4j.SimpleTest - Test test
If you see this it means your expression was evaluated
Elephant
If you see this it means your expression was evaluated
Elephant
16 [main] DEBUG com.singtel.test.slf4j.SimpleTest - Test test, test
If you see this it means your expression was evaluated
Zebra
If you see this it means your expression was evaluated
Zebra
If you see this it means your expression was evaluated
Zebra
16 [main] DEBUG com.singtel.test.slf4j.SimpleTest - Test test, test, test
Conclusion
With disabled logging advantage:
debug(String format, Object arg)
debug(String format, Object arg1, Object arg2)
debug(String format, Object[] argArray)
Without disabled logging advantage:
debug(String msg)
Therefore, if you are migrating from another framework to SLF4J, perhaps Log4J (like me), you need to migrate all your existing loggers into parameterized forms to take advantage of the disabled logging feature. Which otherwise you would have to put around an ugly if/else construct (which the rest of the SLF4J folks – i can assure you, are not doing =p)
Examples of Migration
log.debug("I am here") -> log.debug("I am here")
log.debug("My name is " + name) -> log.debug("My name is {}", name)
log.debug("My name is " + name + " age is " + age) -> log.debug("My name is {} age is {}", name, age)
log.debug("My name is " + name + " age is " + age + " interest is " + interest) -> log.debug("My name is {} age is {} interest is {}", new String[]{name, age, interest})
Notice that when there are three or more variables, you need to use the overloaded method that takes in a String array.
That’s all for now!
Source code / Eclipse project download