JAVA – java.beans.Introspector odd behavior discovering javabeans properties – Is this is a bug?

We use DWR extensively in our AJAX enabled apps. Well the other day I found this weird case where some of our beans properties were not being properly set when being converted from Javascript to Java.
Looking at the source I saw how DWR uses the Introspector on its BeanConverter. This also true for other utils such as Apache commons BeanUtils and PropertyUtils.

I’m Probably missing something obvious here, but regardles of this beans conforming to the Javabeans spec or not the way the introspector finds setter and getters seems backwards to me.

If a bean implements an interface with different return types on its getter than the interface but compatible with the interface the Introspector is unable to see that there are valid accessors in the bean.
I wrote a very simple test case that shows this behavior and possible nasty workaround using reflection.
I wrote all classes and interfaces in the same file but you can use the main method to test with your own classes and you’ll see that the behavior is the same.

I’m not an expert in the javabeans spec and if I’m missing something obvious please let me know.

I also found this post at sun’s forums where other people think this is backwards .

http://forums.sun.com/thread.jspa?threadID=5404791

 
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Method;
 
/**
 * Shows odd behavior when using an introspector from the java.beans api
 */
public class IntrospectorPossibleBugTest {
 
	/**
	 * Marker interface for all locations
	 */
	interface Location {
	}
 
	/**
	 * A City is a location
	 */
	class City implements Location {
	}
 
	/**
	 * Marker interface for people, a person must have a location assigned
	 */
	interface Person {
		Location getLocation();
	}
 
	/**
	 * A worker is a Person and should have a location that is actually a City
	 */
	static class Worker implements Person, Serializable {
 
		private City location;
 
		public City getLocation() {
			return location;
		}
 
		public void setLocation(City location) {
			this.location = location;
		}
 
	}
 
	/**
	 * This small test cases shows the odd behavior.
	 * Even though Worker conforms with the getters and setters for the javabean spec the
	 * Introspector seems to not be able to find any setter for the property location.
	 * Seems like instead of following a bottom up loockup for property accessors it starts and stops once it
	 * finds a compatible property in one of the implemented interfaces.
	 */
	public static void main(String... args) throws IntrospectionException {
		BeanInfo info = Introspector.getBeanInfo(Worker.class);
		PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
		for (PropertyDescriptor descriptor : descriptors) {
			if (!descriptor.getName().equals("class")) {
				System.out.println("property: \t\t\t\t\t\t" + descriptor.getName());
				System.out.println("getter: \t\t\t\t\t\t" + descriptor.getReadMethod());
				System.out.println("getter returns: \t\t\t\t" + descriptor.getReadMethod().getReturnType());
				System.out.println("setter: \t\t\t\t\t\t" + descriptor.getWriteMethod());
				String propertyName = descriptor.getName();
				String setterName = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
				Method setter = findMethodImplFirst(Worker.class, setterName, City.class);
				System.out.println("setter with reflection: \t\t" + setter);
			}
		}
 
	}
 
	/**
	 * workaround for introspector odd behavior with javabeans that implement interfaces with comaptible return types
	 * but instrospection is unable to find the right accessors
	 *
	 * @param currentTargetClass the class being evaluated
	 * @param methodName		 the method name we are looking for
	 * @param argTypes		   the arg types for the method name
	 * @return a method if found
	 */
	public static Method findMethodImplFirst(Class<?> currentTargetClass, String methodName, Class<?>... argTypes) {
		Method method = null;
		if (currentTargetClass != null && methodName != null) {
			try {
				method = currentTargetClass.getMethod(methodName, argTypes);
			} catch (Throwable t) {
				// nothing we can do but continue
			}
			//Is the method in one of our parent classes
			if (method == null) {
				Class<?> superclass = currentTargetClass.getSuperclass();
				if (!superclass.equals(Object.class)) {
					method = findMethodImplFirst(superclass, methodName, argTypes);
				}
			}
		}
		return method;
	}
 
}

output:

property: location
getter: public InstrospectorPossibleBugTest$Location InstrospectorPossibleBugTest$Worker.getLocation()
getter returns: interface InstrospectorPossibleBugTest$Location

setter: null


setter with reflection: public void InstrospectorPossibleBugTest$Worker.setLocation(InstrospectorPossibleBugTest$City)

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • TwitThis
  • email
  • FriendFeed
  • PDF
  • Slashdot

This post is tagged , , ,

don't '

2 Responses

  1. Raul Raja says:

    Yes, just got an email and It is a bug!
    Acknowledge by Sun and soon to be published at http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6921637

Leave a Reply

Comments may be held for moderation, please do not repost. I reserve the right to remove any inappropriate or off-topic comments. If you plan on sharing helpful code, please pass it through Postable first. Want other to know who you are? Register a Gravatar.





Sponsored Links

Categories

Pages

mousetrap bar muppets music relocate server share 1965 peace prize recipiant ai wo koete focus macro for warlock 12 steps of 12 step program duchess restaurant in norwalk ct nubian heritage harlem ferry from kos to lesvos american famaly ins approach meeting discuss forward opportunity 2008 topps update highlights yankees bern north carolina alcohol drug halfway houses phoenix az bartender 4 cindysthrows.com 1st global national conference girls yuri rimini coast icu and ethic girls basketball brethren christian high school codes to the legend of zelda association-office.com blood elf priest dry brushing cabinets free needlepoint slipper pattern aaacap.org gluten free sauces cast and crowns butternut squash ravioli chicago 1920 s style shutter hinges butterflies lake morton alabama malamute 1996 jaguar oil pan anita denise fuller 72 listening skills curved chain nose pliers kari byron pics mythbusters afghan and fruit of the spirit a sweet science fair project discourse markers activities for tefl fractal mac os x dexadine.com bass companion cassie cato partingwishes.com bittorrent free downloader mac apostles today boba fet and leia bonsai societies newsletters coupon code dvdxpress kiosk penguin wild tangent crack 12 step bible burroughs farms brighton michigan penske rental in chico california chocolate coconut truffles copy a locked file brick paving driveway efi smithsonian tours ball draining blowjobs aircraft latrine discharge educacion locke benjamin james loves born in tennessee east brunswick nj vo tech email contact adresses ministers in usa yogafamily.com aol always sunny in philadelphia 2020 automotive group az christmas teas at hotels game ideas for family reunions 2x 4 saddle rack florida radon training brinkmann charcoal smoker modification bali hindu hawks ridge duluth minn ace bowling ball bargains.com arizona motto ditat mongolian barbeque denver buy fujitsu scansnap color image scanner .22 stirling rifles blue spiny lizard ancient stone walls in oakland ca cherry tree leaf parasites elderberry shrubs piragis.com hbs and mpc provider dandy vom hause neubrand kg frontierairline.com box sash windows kent wee ride calgon catalytic carbon filters family homestay in kyoto church choir robes 3288 tranquility lane ao calculate multi range requirement beliefs of messianic judaism charlie bit me utube lakers apparel civil-war.com how to get harder erections tartanstore.net deux de coeur download sega saturn emulator defiance movie watching free child to cherish handprint ornament aftermarketsupport.com benjamin m curry saginaw mi cityofphoenix.gov anakin skywalker darth vader bios not acpi compliant big toe manipulation ac schnitzer facelift lip 92 silver eagle coach billy peterson csi abdomen fat getting large pagesvpp.com 108mbps gaming adapter removeable antenna air bake muffin maris carey touch my body bunting bearings ku nudesville.com 02 pt crusier touring edition manual craiglist fargo how may kkk members are there tilley.com caviar yamaha a life of faith dolls outrageous blondes foodsafeschools.org chesapeake general hosp youngsrvcenters.com globe weis folders online news pakistani channel aloe vera ears campgrounds by wildwood beach new jersey 138 highway closure fgcdirect9.com 6.5 crank sensor tomb-raider-anniversary.com alhambra california newspaper bobble fish days of elijah lyrics bk 2160 parts lloyd james wingate susannah cannon camera retailers honduras 2002 mustang gt spark plugs australian chemist ixsweb.com catholic monastery tennessee carpel tunnel syndrome in golfers electoral college federalist papers australian carp record el segundo stick n stein dodge dually big tires ankle fractures in pediatric patients 1975 toyota celica for sale 115th police academy cadets austin texas conspiracy theory robots downloading soul list of common transitional words dr horner in belleville il leech inside urethra artery inflamation cannondale adventure 800