Jan 31, 2013

[Solved] WARN No appenders could be found for logger

Posted Jan 31, 2013

log4j:WARN No appenders could be found for logger (com.turn.ttorrent.common.Torrent).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

If you are encountering the error above when you're running a program that uses log4j, the solution is to add a log4j.properties that can be seen by the class loader. Normally it's in the "src" folder of your Java project:

Here's an example of log4j.properties content:

log4j.rootLogger=INFO, stdout

log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

Jan 30, 2013

Imgscalr and DPI

Posted Jan 30, 2013
In my previous post, I practically hailed imgscalr as, arguably, the best native Java library for resizing images or creating thumbnails.

This entry is a follow-up for setting the DPI of jpeg output of a Java image. Note that this only works if your output is in jpeg format:

BufferedImage img = ImageIO.read(new File("c:/img/test.jpg"));

BufferedImage scaledImg = Scalr.resize(img, Mode.AUTOMATIC, 640, 480);

File destFile = new File("c:/img/resized.jpg");

JPEGEncodeParam jpegEncodeParam = JPEGCodec.getDefaultJPEGEncodeParam(scaledImg);
final int dpi = 300;
jpegEncodeParam.setQuality(0.85f, false);

FileOutputStream fis = new FileOutputStream(destFile);
try {
  JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(fis);
  jpegEncoder.encode(scaledImg, jpegEncodeParam);
} finally {

System.out.println("Done resizing");

Jan 29, 2013

Resize Images using Java

Posted Jan 29, 2013
When resizing images in Java, one would normally use Image.getScaledInstance() but it has been proven that this is not the most efficient way to scale images, in terms of quality, performance and resource usage.

An alternative would be ImageMagick which is a popular tool used for programmatically resizing images. However, it wasn't implemented in Java so you still need an interface for it a.k.a. JMagick. This could be a pain especially when you need to set-up additional dependencies just to resize images.

The best solution I found is to use imgescalr, a native Java library for resizing images. It uses hardware acceleration if available. The best thing about it is you don't have to set-up dependencies. It has been tested and used in production environments, so it should be reliable. Here's the link to their website and github.

BufferedImage img = ImageIO.read(new File("c:/img/test.jpg"));
BufferedImage scaledImg = Scalr.resize(img, Mode.AUTOMATIC, 640, 480);
File destFile = new File("c:/img/resized.jpg");
ImageIO.write(scaledImg, "jpg", destFile);
System.out.println("Done resizing");

Jan 22, 2013

DBVisit Standby Review

Posted Jan 22, 2013
DBVisit Standby is a tool for creating standby database for Oracle db which ensures high availability and protection of data. This is very similar to what Oracle Data Guard does, but before you can use it, you have to upgrade to Enterprise Edition (EE) which costs money. This is the main selling point of DBVisit Standby because it can work with Oracle Standard Edition (SE).

The cost of Oracle 11g Enterprise is $47,500 / processor + first year support $10,500 which I cannot uncheck so it means it's mandatory. Oracle Data Guard costs $10,000 / processor + $2,200 first year support. The total cost of the Oracle Data Guard solution is a whopping $70,200!

Let's try to compute the cost of DBVisit solution. The cost of Oracle 11g Standard is $17,500 / processor + $3,850 first year support. The most expensive DBVisit Standby option is $14,342 + $3,586 for 1 year support. Total cost is $39,278, a 44% savings compared to Oracle Data Guard solution.

I haven't tried DBVisit personally, because I don't need it but upon checking the forums and blogs, the problems encountered by users are more of set-up related or something went wrong in the back-up process. I'm yet to find a major problem in data corruption, but according to DBVisit team in a forum post, it checks the integrity of the transferred archive log and if it does not match the original log, it retries until it reaches a threshold before it stops and notifications are sent.

In summary, seems DBVisit employs a comprehensive integrity check. And even if data were corrupted in the main destination, there are several ways to fix it since it has several backup mechanisms in place.

Initial impression is that I'm comfortable to use the product because aside from ensuring data integrity, it has good documentation, helpful community and active development team (in case something wrong happens). But again, this is just my impression.

I have checked the last 60 entries of DBVisit forums regarding technical issues, and almost all have a solution and a reply within 1-3 working days, sometimes they even release a new version within 1-2 days of the issue. They have a very active development team which responds to user concerns. This, in my opinion, is one of the most important strengths of DBVisit. I remember a different scenario when I was using Alfresco, I looked at their forums and many issues are left unresolved, even issues we personally encountered.

In this informal review (because I haven't tried the product personally), I'll give DBVisit Standby a rating of 4 out of 5 stars. -Manny

Discard changes in git

If you want to revert your changes made in a given directory with git versioning, execute this command:

git clean -df & git checkout -- .

This will also handle staged and unstaged files.

Jan 10, 2013

[Solved] Property 'cornerRadius' cannot be found in forward class object 'CALayer *'

Posted Jan 10, 2013
When I tried the following:

UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectZero];
myLabel.layer.cornerRadius = 2.0f;
[myLabel release];

I get an error: Property 'cornerRadius' cannot be found in forward class object 'CALayer *'

The solution is to import the QuartzCore framework:

#import <QuartzCore/QuartzCore.h>

Happy coding!

Jan 8, 2013

Get GMT in iOS using NSTimezone

Posted Jan 8, 2013
There are cases that you want to get the GMT string of an iPhone / iPad device. Here's how you can do it:

  NSTimeZone *localTime = [NSTimeZone systemTimeZone];
  CGFloat gmt = ([localTime secondsFromGMT]/60.f/60.f);
  NSMutableString *gmtStr = [[[NSMutableString alloc] init] autorelease];
  int hours;
  if (gmt < 0) {
    hours = ceil(gmt);
  } else {
    hours = floor(gmt);
  int minutes = abs(round((gmt - hours) * 60));
  if (gmt >= 0) {
    [gmtStr appendFormat:@"+%d",hours];
  } else {
    [gmtStr appendFormat:@"%d",hours];
  if (minutes > 0) {
    [gmtStr appendFormat:@":%02d", minutes];
  NSLog(@"GMT is %@", gmtStr);

Jan 4, 2013

UIView is blurred after setting its width (autoresizingmask / anchoring related)

Posted Jan 4, 2013
Blurring of views usually occurs when the device is trying to fit 1 point to two pixels. This happens when you have an x or y origin with a decimal place. X or Y origins can have unintentional decimal places when you're setting the "center" property of the view instead of the actual frame. It is more apparent in non-retina devices because they have fewer pixels.

Unintentional decimal places in a view's origin can also occur when you set the width of a view that has an autoresizingmask where the view is automatically anchored to its parent and the system is adjusting the origin for you.

In my experience, I get a blurred view in landscape mode when my I set the width of my anchored view to an odd number, so I just make sure I always set the width to an even number.

CGRect myRect = self.view.frame;
int myRectInt = (int) roundf(myRect.size.width);
if (myRectInt % 2 != 0) {
  myRect.size.width = myRectInt + 1;
self.view.frame = myRect;

Happy coding!

Converting CGFloat to int [Objective-C]

There are cases that you want to convert float numbers to integer. One example is when you're using a frame's attribute, say, frame.size.width and you want to know if it's odd or even number. Before you can do a modulo operation, the numbers must be in integer format.

The easiest way is to round the float value first and typecast it to int.

int integerWidth = (int) roundf(myFrame.size.width);

Hope this helps!