URL getContent returns Virtual File instead of ImageProducer in JBoss AS 6.0.0
panchonb May 24, 2011 11:21 PMHello,
We have been tasked to move from JBoss 4.2.3GA to JBoss AS 6.0.0.FINAL. We have run into an issue where a thirdparty component is throwing a NullPointer exception.
We traced this exception down to a resource file (image) not working anymore. In JBoss 4.2.3.GA this would work fine, but now in JBoss 6 it doesn't.
After finding that the Image was now null, we again did more digging. Turns out it is a change in how URL.getContent works.
If the image is loaded in a normal Java environment outside of JBoss, the image works fine and the reference to the image is non-null. When we then use the same exact class, in the same exact Jar but in JBoss, the image gets set to null.
Here is an example that works from a straight up Java environment, but not in JBoss:
package example.loadimage.fail;
import java.awt.Image;
import java.beans.SimpleBeanInfo;
public class LoadImageTest extends SimpleBeanInfo {
public Image image;
public LoadImageTest(){
image = loadImage2("icon.png");
}
/**
* @param args
*/
public static void main(String[] args) {
LoadImageTest test = new LoadImageTest();
System.out.println("Is image null? " + (test.image == null));
}
// Note: This method was pulled out of the JDK src file for SimpleBeanInfo.java.
// This allows for easier debugging, you can actually see the local variables.
public java.awt.Image loadImage2(final String resourceName) {
try {
final Class c = getClass();
java.awt.image.ImageProducer ip = (java.awt.image.ImageProducer)
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
java.net.URL url;
if ((url = c.getResource(resourceName)) == null) {
return null;
} else {
try {
return url.getContent();
} catch (java.io.IOException ioe) {
return null;
}
}
}
});
if (ip == null)
return null;
java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
return tk.createImage(ip);
} catch (Exception ex) {
// will end up here because the PrivilegedAction returns something that cannot be cast
// to an ImageProducer when this is run in JBoss AS 6.0.0.FINAL. In JBoss the returned
// object will be a VirtualFile instead of an ImageProducer.
return null;
}
}
}
This class will print out false when run from the main method, meaning the image member is not null.
Here is a JSP that will print true because the image is now null:
<%@page import=" example.loadimage.fail.LoadImageTest"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
out.print("Testing<br />");
LoadImageTest test = new LoadImageTest();
out.print("Is test.image null? " + (test.image == null) + "<br />");
%>
</body>
</html>
This seems to be a change in how an image is returned. Instead of returning an ImageProducer from the url.getContent() method, it returns a VirtualFile. Hence, the reason for the ClassCastException which is then swallowed and a null value returned.
Please, note that the loadImage2(...) method is taken directly from the JDK src of SimpleBeanInfo.java. It was extracted to ease debugging.
Is this a bug in JBoss? Or is there something we are missing? Modification of the third party component is a last resort we don't really want to do.
Hope this make sense.