Hi Victor,Sure, please find it enclosed.Mind attaching the patch as a unified diff, please? It's easier to read. There are two things here:
Regards, ---rony |
--- E:\svnrgf\remote\bsf\src\org\apache\bsf\util\EngineUtils.java 2004-06-14 19:29:41.000000000 +0200 +++ EngineUtils.java 2005-06-07 11:37:28.114998400 +0200 @@ -1,7 +1,7 @@ /* * The Apache Software License, Version 1.1 * - * Copyright (c) 2004 The Apache Software Foundation. All rights + * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,6 +75,25 @@ // temp directory static BSFClassLoader bsfCL; + // ---rgf, 2003-02-13, determine whether changing accessibility of Methods is possible + static boolean bMethodHasSetAccessible=false; + + // ---rgf, 2003-02-13, determine whether changing accessibility of Methods is possible + static { + Class mc=Method.class; // get the "Method" class object + Class arg[]={boolean.class}; // define an array with the primitive "boolean" pseudo class object + try { + Object o=mc.getMethod("setAccessible", arg ); // is this method available? + bMethodHasSetAccessible=true; // no exception, hence method exists + } + catch (Exception e) + { + bMethodHasSetAccessible=false;// exception occurred, hence method does not exist + } + } + + ////////////////////////////////////////////////////////////////////////// + /** * Add a script as a listener to some event coming out of an object. The * first two args identify the src of the event and the event set @@ -87,7 +106,7 @@ * @param engine BSFEngine which can run this script * @param manager BSFManager of the above engine * @param source (context info) the source of this expression - * (e.g., filename) + (e.g., filename) * @param lineNo (context info) the line number in source for expr * @param columnNo (context info) the column number in source for expr * @param script the script to execute when the event occurs @@ -95,23 +114,23 @@ * @exception BSFException if anything goes wrong while running the script */ public static void addEventListener (Object bean, String eventSetName, - String filter, BSFEngine engine, - BSFManager manager, String source, - int lineNo, int columnNo, - Object script) throws BSFException { + String filter, + BSFEngine engine, BSFManager manager, + String source, int lineNo, + int columnNo, Object script) + throws BSFException { BSFEventProcessor ep = new BSFEventProcessor (engine, manager, filter, source, lineNo, columnNo, script); - try { ReflectionUtils.addEventListener (bean, eventSetName, ep); } catch (Exception e) { e.printStackTrace (); throw new BSFException (BSFException.REASON_OTHER_ERROR, - "ouch while adding event listener: " - + e, e); + "ouch while adding event listener: " + e, e); } } + ////////////////////////////////////////////////////////////////////////// /** * Finds and invokes a method with the given signature on the given @@ -130,10 +149,8 @@ */ public static Object callBeanMethod (Object bean, String methodName, Object[] args) throws BSFException { + // determine arg types. note that a null argtype matches any object type Class[] argTypes = null; - // determine arg types. note that a null argtype - // matches any object type - if (args != null) { argTypes = new Class[args.length]; for (int i = 0; i < args.length; i++) { @@ -144,13 +161,11 @@ // we want to allow a static call to occur on an object, similar // to what Java allows. So isStaticOnly is set to false. boolean isStaticOnly = false; - Class beanClass = (bean instanceof Class) ? (Class)bean : - bean.getClass (); + Class beanClass = (bean instanceof Class) ? (Class)bean : bean.getClass (); // now try to call method with the right signature try { - Method m = null; - + Method m; try { m = MethodUtils.getMethod (beanClass, methodName, argTypes, isStaticOnly); @@ -161,23 +176,27 @@ // if args is null the NullPointerException will get caught // below and the right thing'll happen .. ugly but works for (int i = 0; i < args.length; i++) { - if (args[i] instanceof Number) { + if (args[i] instanceof Number) + { // byte is convertible to all primitive numeric types, // so this'll find anything in that order and the // actual type will be that specified by the method decl - argTypes[i] = byte.class; - if(args[i] instanceof Float) - argTypes[i] = float.class; - else if(args[i] instanceof Double) - argTypes[i] = double.class; + if (args[i] instanceof Byte) argTypes[i] = byte.class; + // 2005-06-08, rgf, *must* be given, or signatures not found! + else if (args[i] instanceof Short ) argTypes[i] = short.class; + else if (args[i] instanceof Integer) argTypes[i] = int.class; + else if (args[i] instanceof Long) argTypes[i] = long.class; + + else if (args[i] instanceof Float) argTypes[i] = float.class; + else if (args[i] instanceof Double ) argTypes[i] = double.class; + } + else if (args[i] instanceof Boolean) argTypes[i] = boolean.class; + // ---rgf, handle also the case of "Character" + else if (args[i] instanceof Character) argTypes[i] = char.class; } - else if (args[i] instanceof Boolean) - argTypes[i] = boolean.class; - else if (args[i] instanceof Character) - argTypes[i] = char.class; - } - m = MethodUtils.getMethod (beanClass, methodName, - argTypes, isStaticOnly); + + m = MethodUtils.getMethod (beanClass, methodName, argTypes, + isStaticOnly); } catch (Exception e2) { // throw the original throw e; @@ -185,7 +204,21 @@ } // call it, and return the result + try { return m.invoke (bean, args); + } + catch (Exception e3) // 2003-02-23, --rgf, maybe an IllegalAccessException? + { + if (e3 instanceof IllegalAccessException && + bMethodHasSetAccessible && + Modifier.isPublic(m.getModifiers()) ) // if a public method allow access to it + { + m.setAccessible(true); // allow unconditional access to method + return m.invoke (bean, args); + } + // re-throw the exception + throw e3; + } } catch (Exception e) { // something went wrong while invoking method @@ -194,13 +227,13 @@ null; throw new BSFException (BSFException.REASON_OTHER_ERROR, "method invocation failed: " + e + - ((t==null) ? "" : - (" target exception: " + t)), t); + ((t==null)?"":(" target exception: "+t)), t); } } + ////////////////////////////////////////////////////////////////////////// /** - * Creates a new bean. The signature of the constructor that's invoked + * Creates a new bean. The signature of teh constructor that's invoked * is first taken as the types of the args, but if that fails, this tries * to convert any primitive wrapper type args to their primitive * counterparts to see whether a method exists that way. If it does, done. @@ -214,11 +247,11 @@ * org.apache.cs.util.MethodUtils for the real * exceptions that can occur). */ - public static Object createBean (String className, Object args[]) - throws BSFException { + public static Object createBean (String className, + Object args[]) throws BSFException { Bean obj; - Class[] argTypes = null; + Class[] argTypes = null; if (args != null) { argTypes = new Class[args.length]; for (int i = 0; i < args.length; i++) { @@ -228,8 +261,7 @@ try { try { - obj = ReflectionUtils.createBean (null, className, - argTypes, args); + obj = ReflectionUtils.createBean (null, className, argTypes, args); return obj.value; } catch (NoSuchMethodException me) { // ok, so that didn't work - now try converting any primitive @@ -238,15 +270,16 @@ // if args is null the NullPointerException will get caught // below and the right thing'll happen .. ugly but works for (int i = 0; i < args.length; i++) { - if (args[i] instanceof Number) + if (args[i] instanceof Number) { + // byte is convertible to all primitive numeric types, + // so this'll find anything in that order and the + // actual type will be that specified by the method decl argTypes[i] = byte.class; - else if (args[i] instanceof Boolean) + } else if (args[i] instanceof Boolean) { argTypes[i] = boolean.class; - else if (args[i] instanceof Character) - argTypes[i] = char.class; } - obj = ReflectionUtils.createBean (null, className, - argTypes, args); + } + obj = ReflectionUtils.createBean (null, className, argTypes, args); return obj.value; } catch (Exception e) { // throw the previous exception @@ -258,6 +291,7 @@ e.getMessage (), e); } } + ////////////////////////////////////////////////////////////////////////// /** * Given a class return the type signature string fragment for it. @@ -269,24 +303,25 @@ */ public static String getTypeSignatureString (Class cl) { if (cl.isPrimitive ()) { - if (cl == boolean.class) + if (cl == boolean.class) { return "Z"; - else if (cl == byte.class) + } else if (cl == byte.class) { return "B"; - else if (cl == char.class) + } else if (cl == char.class) { return "C"; - else if (cl == short.class) + } else if (cl == short.class) { return "S"; - else if (cl == int.class) + } else if (cl == int.class) { return "I"; - else if (cl == long.class) + } else if (cl == long.class) { return "J"; - else if (cl == float.class) + } else if (cl == float.class) { return "F"; - else if (cl == double.class) + } else if (cl == double.class) { return "D"; - else + } else { // (cl == void.class) return "V"; + } } else { StringBuffer sb = new StringBuffer ("L"); sb.append (cl.getName ()); @@ -294,6 +329,7 @@ return sb.toString().replace ('.', '/'); } } + ////////////////////////////////////////////////////////////////////////// /** * Load a class using the class loader of given manager. If that fails @@ -310,15 +346,15 @@ public static Class loadClass (BSFManager mgr, String name) throws BSFException { ClassLoader classLoader = mgr.getClassLoader (); - try { return (classLoader == null) ? Class.forName (name) : classLoader.loadClass (name); } catch (ClassNotFoundException e) { // try to load it from the temp dir using my own class loader try { - if (bsfCL == null) + if (bsfCL == null) { bsfCL = new BSFClassLoader (); + } bsfCL.setTempDir (mgr.getTempDir ()); return bsfCL.loadClass (name); } catch (ClassNotFoundException e2) {
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]