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.