Sunday, June 28, 2009

Sunday, June 14, 2009

Saturday, June 13, 2009

LookupListener problem?

There are many unanswered threads to this question. The common issue is that the resultChanged(...) method is never triggered!! Here is a proper use-case scenario (note the comments, they provide tips to avoid common loopholes)
public SomeClass extends LookupListener
{
//It is important that you hold a reference to Lookup.Result
//so that it doesn't get garbage collected. This also applies to Lookup.Template
private Lookup.Result result = lookup.getDefault().lookupResult(MyInterface.class);

public SomeClass()
{
result.addLookupListener(this);

//It is important to call this method once...otherwise
//resultChanged(...) method is never triggered!!
resultchanged(new LookupEvent(result));
}

public void resultChanged(LookupEvent ev)
{
//do your stuff here...
}
}
If you still have problems, then check the META-INF/services folder of your implementation, there is probably a typo in the flat file. Its better to use @Service annotation to avoid such mistakes.

Plugin manager for standalone swing apps

Lookup API provides more features than the typical ServiceLoader mechanism introduced in JDK 6. It allows you to listen to changes using LookupListener. If your not aware of Lookup API, please read about it here before continuing any further. For a more comprehensive tutorial on the subject, check out this screencast

Lookup API provides amazing decoupling capabilities to your application, even in standalone and non visual applications. The problem comes when you have to install or remove modules from your applications (implementations of an interface). In Netbeans platform the plugin manager would automatically do this for you. To utilize the benefits of LookupListener, one has to add the module jar files to the classpath (at run time).

This however cannot be achieved directly, here's a reflection hack to get it done:
/**
* Rescans the given folder and adds all the Jar files (plugins)
* to class path...simply ignores if a jar file is already added...
*
* @param path The folder containing plugins...
* @throws java.io.IOException
*/
public void rescan(String path) throws IOException
{
File pluginFolder = new File(path);
File plugins[] = pluginFolder.listFiles(new FileFilter()
{
public boolean accept(File pathname)
{
if(pathname.getPath().endsWith(".jar"))
return true;
else
return false;
}
});

for(File f : plugins)
{
addPlugin(f.toURI().toURL());
}
}

/**
* The url (preferably jar) to be added to the classpath.
* This is like an install plugin thingy...
* Must be used in place of {@link #rescan(java.lang.String) rescan} method
* if a single new plugin is to be installed...gives good performance ups
*
* @param url The url to be added to classpath
*/
public void addPlugin(URL url) throws IOException
{
addURLToClassPath(url);
}

/**
* To avoid un-necessary object creation on method calls...
*/
private static final Class[] parameters = new Class[]{URL.class};
/**
* Adds a URL, preferably a JAR file to classpath. If URL already exists,
* then this method simply returns...
*
* @param u The URL t be added to classpath
* @throws java.io.IOException
*/
private void addURLToClassPath(URL u) throws IOException
{
URLClassLoader sysloader = URLClassLoader)ClassLoader.getSystemClassLoader();

boolean isAdded = false;
for(URL url : sysloader.getURLs())
{
if(url.equals(u))
isAdded = true;
}
if(isAdded)
return;

Class sysclass = URLClassLoader.class;
try
{
Method method = sysclass.getDeclaredMethod("addURL",parameters);
method.setAccessible(true);
method.invoke(sysloader, new Object[]{ u });
}
catch (Throwable t)
{
t.printStackTrace();
throw new IOException("Error, could not add URL to system classloader");
}
}
In the above code we are adding a URL (typically pointing to a jar file) to the system classloader by invoking its private method via reflection.

In your plugin manager...all you have to do is paste the jar file to a certain folder (say user.dir/plugins), then execute the following code to add jars to classpath:

/**
* Rescans the given folder and adds all the Jar files (plugins)
* to class path...simply ignores if a jar file is already added...
*
* @param path The folder containing plugins...
* @throws java.io.IOException
*/
public void rescan(String path) throws IOException
{
File pluginFolder = new File(path);
File plugins[] = pluginFolder.listFiles(new FileFilter()
{
public boolean accept(File pathname)
{
if(pathname.getPath().endsWith(".jar"))
return true;
else
return false;
}
});

for(File f : plugins)
{
addPlugin(f.toURI().toURL());
}
}

/**
* The url (preferably jar) to be added to the classpath.
* This is like an install plugin thingy...
* Must be used in place of {@link #rescan(java.lang.String) rescan} method
* if a single new plugin is to be installed...gives good performance ups
*
* @param url The url to be added to classpath
*/
public void addPlugin(URL url) throws IOException
{
addURLToClassPath(url);
}
That's it! the newly registered service providers can be caught in resultChanged(...) method of the LookupListener. Similarly you can remove items from the classpath to deactivate the plugins from your application, i'll leave that as your home work assignment :)

Wednesday, June 10, 2009

lookup third party service impl of an interface

If you have a jar file containing implementations of an interface that you want to be discovered by lookup...here's what you do:

1) Use library wrapper wizard in Netbeans to create a jar module wrapper.
2) Create a folder META-INF/services in the wrapper module.
3) Create a file in META-INF/services named after the fully qualified name of the interface containing the fully qualified names of the implementations (one per line)

That's it!
Third party service implementations to now be discovered by the global lookup on startup.

Saturday, June 6, 2009

Unnecessary object creation...

Most of you might already know about this. I just found this out while working on my open source project JNeuralNet.

I had this situation:


loop
{
Double d = someclass.compute();
}
When i ran the profiler. I noticed that the major portion of CPU was going into Double object creation. That's when i realized that its the classloader overload everytime the object is being created..so this is what i did:

//init variable...
Double d = 0.0;
loop
{
d = someclass.compute();
}
This simple optimization reduced a lot of CPU overload! Also if u have situations such as:

loop
{
Obj o = new Obj();
}
If feasible...try using:

Obj o = new Obj();
loop
{
//use o...
o.set(abc);
}
This approach is not always feasible...especially if you intend to use the reference of the object elsewhere, my point is, to reduce object creation wherever feasible.

Friday, June 5, 2009

My theory on time travel...

Already tortured people by giving this presentation back in my 8th semester...here goes:

I have two solid conclusions:
1) Its possible to view past.
2) Not possible to travel back in past or is a very bad idea!

1st assumption is an easy one to crack...you see this phenomenon every day (every night actually). Just look up at the sky...see the stars. What u actually see is the past. That star might have died by now...since it is 100's of light years away...what you're actually seeing is 100 light years backward.

As for the 2nd assumption...lets start with the hypothesis that it is possible to travel to past. Now imagine that you do something to trigger the death of your past self...It means that you never took the path that led you to travel back to the past, a direct contradiction.

so let us now suppose that its not possible to kill your past self. It might mean that your consciousness might merge with the past self and u forget everything about the future u came from...meaning that in future u again do the same time travel thingy., come back to past. Dude, you're now stuck in an indefinite loop.

Third option, according to string theory, every universe represents a possibility. suppose u travel in past and do something different it means that you have shifted the future timeline to a new parallel universe...meaning that u effectively destroyed the current universe and connected the future events to another one...destruction of a universe...certainly sounds like a bad idea!

Crazy comments are most welcome!!

My theory of good and bad

Pardon me for the language folks, but i think good and bad is BULL CRAP! Here's what i believe...

Some clever saint/person must have thought of this idea to keep things in control...so that the world doesn't go chaotic.

Just think of this for a moment...U say that a good thing is good because if gives u the internal satisfaction or whatever. You know what i think...i feel its because of the society/environment you're brought up in. Imagine a society where they'd preach that hurting some one is a good thing. In that case, hurting someone may give u that internal satisfaction...just like the way animals kill each other...no moral code whatsoever.

So in conclusion...there is no good and bad. Its human invented! Don't get the wrong idea, im not telling u to become bad or something. Its just my option...thought it was interesting and shared it!

Give...dont expect things back!

Expectation is your worst enemy. Always help...if possible go out of the way to help others. I believe in karma and have a belief that whatever u do comes back to you. Please don't expect things in return...I have seem many people getting hurt because of this. Just take the happiness as a return gift for the moment. In the worst of times, the favor will return by itself!

Afterall they're humans too!

Were there times when u get scared of your boss, faculty, giving presentations? Just remember this one thing, bottom line they're also humans...just like us. They have also made mistakes and must have been nervous at some point.

Just imagine yourself in their position. Would have just laughed it off wouldn't you? So just tell them whatever it is that you're so hesitant about. Want a pay raise...wouldn't agree with their ideas, SPEAK OUT! At the most what will happen? You may get fired or ridiculed at...but will always be happy that you did the RIGHT THING!...In the end its the satisfaction that matters.