Archive for coding

Log4j writing to a dynamic log file for every run

In my recent project, I was using Log4J and I had a requirement where I had to write to a new dynamic log file every time and the name of the log file was determined at runtime. In specific terms each run would produce a Project and the log file had to reflect the project name. Since this project name could be repeated across runs, the timestamp needed to be added to the log file. I searched across Google and didn’t find much help in this regard. So I decided to post the code I wrote.

I didn’t want to lose setting the log levels from the log4j.xml file and wanted all the options I could configure for the FileAppender except the file name. The file name was configured too, but the code had to overwrite and create a new file at runtime. Here is the code..

Date projDate = new Date(Long.parseLong(project.getTimeStamp()));
StringBuffer dateStr = new StringBuffer();
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy_MM_dd_HH_mm_ss”);
dateStr = sdf.format(projDate, dateStr, new FieldPosition(0));
String logFileName = logsDir + File.separator + project.getName() + “_” + dateStr.toString() + “.log”;
log.info(“\n**************Log file for this run: ” + logFileName + “\n**************\n”);

Logger rootLogger = Logger.getRootLogger();
Enumeration appenders = rootLogger.getAllAppenders();
FileAppender fa = null;
while(appenders.hasMoreElements())
{
Appender currAppender = (Appender) appenders.nextElement();
if(currAppender instanceof FileAppender)
{
fa = (FileAppender) currAppender;
}
}
if(fa != null)
{
fa.setFile(logFileName);
fa.activateOptions();
}
else
{
log.info(“No File Appender found”);
}

That’s it. The logs were created for each and parallel runs would write to different files…

Comments (4)

Java: Loading an XML file from the CLASSPATH

Today, I faced this issue in Java coding. I needed to load an XML file which was in my classpath but not in the same directory as the classes. The deliverable was a jar and the properties and the configuration XML files were in a different folder and were appended to the classpath at the runtime. The issue was that the file could not be located through the the statement

String fileName = getClass.getSystemResource(“config.xml”).getFile;

Then I thought that it checks relative to the current class and so used the statement

String fileName = ClassLoader.getSystemResource(“config.xml”).getFile;

But then, it wouldn’t still recognize the file. The reason is the same, it checks relative to the classes folder. I did not want to get the classpath from the system and browse through it for the config file since the class path could get larger. A couple of google searches and a little research later, I found the solution. The workaround is by using the following statement

String fileName = Thread.currentThread().getContextClassLoader().getResource(“config.xml”).getFile;

It only makes sense since in the above statement, you get hold of the context class loader and find the path in the entire classpath…

Comments (4)

Power of Java, In deleting the files that Windows cannot

Today, in one of the programs, I messed up a little piece of code that creates a folder in another, which ended up creating folders in an infinite loop. The folder name was ae, but there were so many of them ae in ae in ae …. Then I just wanted to clear the folder and start afresh with the fixed code. But guess what. Windows would not delete the folder because the name is too long. This was the exact error..

“cannot delete the file name you specified is not valid or too long”

I tried from Command prompt and tried other solutions from Google search like assigning a name on shared and trying to delete from network. And nothing worked. That’s when I decided, let’s take Java’s help. Wrote a simple piece of code to loop through until it reaches the final folder and deletes everything. Ran the code and 2 minutes later, everything was gone. One more reason to love Java and being a programmer. Here is the code in case you are interested..

import java.io.File;
public class FileDelete
{

private void deleteFiles(File file)
{
if(file.isDirectory())
{
File child[] = file.listFiles();
for(int i = 0; i < child.length; i++)
{
deleteFiles(child[i]);
}

}
if(!file.delete())
{
System.out.println(“Cannot delete file: ” + file.getAbsolutePath());
}
}
public static void main(String[] args)
{
System.out.println(“Attempting to delete files”);
File _work = new File(“”);
FileDelete fd = new FileDelete();
fd.deleteFiles(_work);
}
}

Comments (2)

Too smart or too novice in Java: Relevance of for loops

During the course of my work, I have had to fix some code written by others and modify existing code for enhanced functionality. In one of such projects, I encountered this piece of code written by someone

for(boolean valid = false; !valid; valid = true)
{
try
{
sp = spf.newSAXParser();
parser = new ProjectParser();
sp.parse(projectFile, parser);
}
catch(Exception e)
{
e.printStackTrace();
log.throwable(e);
throw new RuntimeException((new StringBuilder(“Unable to parse “)).append(projectFile.getAbsoluteFile()).toString());
}
}

Let’s see how this for loop works. It initializes a boolean called valid with a value false. The condition is until valid is false. The increment is making valid true. And then inside the loop, the coder wants to accomplish something. Now what is the point of this for loop at all. Was the for loop used because the coder didn’t know that loops are used for, you guessed right, looping. If he/she just wanted it to run only once, then what is the point of using a for loop at all. How different is the below code from the above code.

try
{
sp = spf.newSAXParser();
parser = new ProjectParser();
sp.parse(projectFile, parser);
}
catch(Exception e)
{
e.printStackTrace();
log.throwable(e);
throw new RuntimeException((new StringBuilder(“Unable to parse “)).append(projectFile.getAbsoluteFile()).toString());
}

This would execute the code only once and that is the desired behavior that was accomplished by using the for loop for once. I think keeping your code clean and staying away from such unnecessary stuff helps you in keeping your code clean and reducing any unwanted bugs. Why turn the hand around the neck to eat something when you could directly eat it.. Is this trying to be too smart or being too much of a novice to know what loops are used for. Or is there something, that I am missing that is something great that I haven’t realized in using this type of code. If someone could elaborate, I would be glad…

Comments (1)

Overcoming cross domain issues through php proxy server in Flex for RSS Reader samples

Today, I took a second look at my home page and decided that the blog link should not directly point to this page and should have an in-built RSS Reader for getting these posts there. And then the troubles started. People who know me already know my website and know that it was built in Flex. I had this idea of an in-built RSS Reader in my home page for long, but whenever I started working on it, I would have weird exceptions on page load, which were not straight forward and I wouldn’t have time to debug them. So it remained the same, a hyperlink to this blog. Today a post on DZone caught my attention and I again tried this. I found a simple example which I implemented in my home page and thankfully everything went cool. But when I put it on the server, another problem started. The cross-domain problem..

The thing about flex is that, while being cool and xml dominated, the biggest problem is with the fact that you cannot load the rss or xml from other websites, without a cross-domain.xml file on the serving domain that lists the calling domain. Now I cannot ask blogger.com to put my domain name in their cross-domain.xml file. Can I ?? So I preferred the alternative route, which is widely written on the net, the proxy server route. And though I do not have Java hosting by my space provider, they support php and went for a simple php script..

<?php
header(‘Content-Type: text/xml’);
$url = ‘http://cognitivecache.blogspot.com/rss.xml’;
$content = file_get_contents($url);
echo $content;
?>

The script looks so simple like a no-brainer right. Nope, that wouldn’t still solve my problem. Because, the blogger wouldn’t let the php script open a stream and I kept ending up with this error

Warning: readfile [function.readfile]: failed to open stream: No route to host..

After changing the scripts from the net thrice hoping the other one would be different, I kept coming back to the same problem. Finally I realized that it could be an issue with Blogger not allowing an incoming connection. Boom, that was it. I changed the code to point to my feed in FeedBurner and that was it. My new code looks like this

<?php
header(‘Content-Type: text/xml’);
$url = ‘http://feeds.feedburner.com/CognitiveCache’;
$content = file_get_contents($url);
echo $content;
?>

Now, The RSS Reader gets its content now and it looks like a nice addition. A Happy ending to lot of time spent indeed !!

If you are still wondering about the whole process, what you need to do, is to burn a feed in FeedBurner and put the above code in a file called proxy.php. Now upload this file to your domain and use the url for xml in your flash file as “http://mydomain.com/proxy.php” and thats it..

Comments (2)

statement.setMaxrows in JDBC vs Oracle rownum in SQL

If you want to limit the number of rows retrieved from an Oracle database in a Java/Servlet application using JDBC, you can accomplish this in two ways. One is using statement.setMaxRows in the JDBC or using rownum in the Oracle SQL.

For example, lets say there are 1000 employee records in the EMPLOYEES table which has the columns: empid, first_name and last_name. In order to retreive the first 200 rows, in java you can say

….

Connection dbConn = db.getConnection();
Statement stmt = dbConn.createStatement();
stmt.setMaxRows(200);
String sql = “select empid, first_name, last_name from employees”;
ResultSet rs = stmt.executeQuery(sql);

……………

This gets you a resultset with 200 rows and everybody is happy. You could have alternatively done that using rownum on your sql query itself without using setMaxRows() on statement like below:

….

Connection dbConn = db.getConnection();
Statement stmt = dbConn.createStatement();
String sql = “select empid, first_name, last_name from employees where rownum<201″;
ResultSet rs = stmt.executeQuery(sql);
……………

Even this time, the resultset has 200 rows and everybody is happy. Now the question is, which one should you use and why. I may not be an expert in talking about this, but here are my observations…

If you are dealing with a table which has relatively less records like in thousands, then either way works just fine. But if you are dealing with potentially huge database which has like millions of records, then I guess using rownum in the sql makes more sense. This is because the impact on your Java heap space would be lesser.

According to JDBC, the implementation of setMaxRows is as given below:
———————————–
The maxRows limit is set to limit the number of rows that any ResultSet can contain. If the limit is exceeded, the excess rows are silently dropped.
————————————

For example, lets say there are 14 million records in a table, from which you want to retrieve the first 3000 rows. If you use statement.setMaxRows(), the JDBC call retreives the entire 14 million records from the database table and sets the first 3000 records on the resultset object. But the retrieval of such huge number of records puts a huge lump of data on your JVM, and you are dependent on the Garbage Collector for retrieval of this space. But if you use rownum in the SQL, then the number of rows retrieved from the DB by JDBC itself is limited and there won’t be any heap space issues. I ran a trial session with our DBA and it was confirmed that the statement.setMaxRows() doesn’t modify the sql using rownum automatically. We traced the session and it was retrieving all the million records. And I came to a conclusion that the heap space issues I was facing was due to the usage of statement.setMaxRows() instead of using rownum on the SQL. Also the speed of retrieval of rows when you limit by rownum could be more, though I don’t have substantial evidence to state it as a fact.

If you are an expert in Java / Oracle Databases and feel that part/total of this post doesn’t make any sense or if it looks like complete bullshit, then please feel to share your expertise on this matter / bash me in the Comments:)

Leave a Comment

Fundamental mistake in Digg web page coding or fooling Diggers??

Everyone knows how famous Digg is today, on the web. So much that Time magazine rated ‘You’ as the person of the year because of the user power created by Digg. And Digg has opened gates for Developers by providing Digg APIs and contests for the best mashup. All these made me think great of Digg and the way the website is coded, but this fundamental flaw in coding the Digg page leaves me stunned. Is it an oversight or an attmept to fool the users??

Here is what I mean. Find the news dugg by any user on Digg by clicking on their link. I am showing the example with the news dugg by me.

As you can see at the bottom, where I circled, there are links to more than 10 pages with the Next button after 10 … But if I click on 9th page for example, here is what I see..

Forget about 9th page, if I click on 4th page, here is what it shows..

So, basically, I had dugg 3 pages worth of news, but even in the second page, it shows me links till 10 pages and more as if I had dugg news worth more than 10 pages. Any programmer who has done basic programming would know how easy it is, to control the number of links for pagination. Calculate the number of diggs a user has, divide it by the number of links you show on each page to figure how many links to show for pagination.

I agree that it may not be a show stopper and it might merely be a small bug, but with the Digg team implementing new comments system and opening up APIs, I would surely expect higher standards of coding. Not impressed much Digg team.. So as I said above, is this just an oversight or an attempt to show off a lot of posts to the Digg users. I would side with the former but still expect them to fix this..

Comments (2)