From: David G. <gr...@gm...> - 2008-08-31 13:06:39
|
Can anyone suggest a way of trapping exceptions in runtime script execution ? My app executes scripts at runtime, taken from files. Each script is in essence a class definition based on an abstract class in my Java. So whatever is in the script, I know it should have a some key methods defined in the abstract base class, and these are called from my java code. I read the script into my interpreter myInterpreter.execfile(scriptStream); and this is void with no exceptions so I cannot really tell at that point if script is OK Then I get a reference for the class PyObject cls = interpreter.get(nameOfMyClass); If cls != null then I think can be reasonably sure it found a valid class in the interpreter namespace I try to instantiate the class PyObject cls_instance = cls.__call__(); Then I convert that into a java object Object o = cls_instance.__tojava__(myAbstractClass.class); If o != Py.NoConversion then I presumably have a usable java object. I then cast o to (myAbstractClass) and I can start treating it as an instance of myAbstractClass and call the base class methods. This works a treat. But suppose one of the methods implemented in the script contain a dodgy bit of Python code ? Currently I find out at runtime when - it does not work (not always apparent) - a load of (admittedly quite informative) Jython error messages appear on stderr But how can I capture this programmatically in my calling Java code ? As far as Java is concerned, I called a method called "baseMethod1()" on a normal instance of myAbstractClass . I guess what I would like to be able to do is say in my abstract Java class definition something like public abstract class myAbstractClass { // This method will be implemented in my Jython script public abstract void baseMethod1(...) throws SomeSortOfException; } and find a way to have the Jython Interpreter automatically throw this SomeSortOfException if it encountered a problem in my code at runtime. Is there a setting for this ? I would rather not have to add a load of code in the script itself for this because my whole aim here is to make the scripts themselves simple and hide any infrastructure details from the user who might have to view and tweak the scripts. Hope I have explained this clearly. Thanks in advance. David Griffin |
From: Alan K. <jyt...@xh...> - 2008-09-04 12:15:05
|
[David] > Can anyone suggest a way of trapping exceptions in runtime script execution ? Is this what you mean? //============== CatchExceptions.java ===================== import org.python.core.*; import org.python.util.PythonInterpreter; public class CatchExceptions { public static void runDodgyCode ( PythonInterpreter interp, String codeString ) { try { interp.exec(codeString); } catch (PyException pyx) { if (pyx.type == Py.IndexError) System.err.println("This code >>>"+codeString+"<<< gave an index error"); if (pyx.type == Py.KeyError) System.err.println("This code >>>"+codeString+"<<< gave a key error"); if (pyx.type == Py.SyntaxError) System.err.println("This code >>>"+codeString+"<<< gave a syntax error"); if (pyx.type == Py.ZeroDivisionError) System.err.println("This code >>>"+codeString+"<<< gave a zero division error"); System.err.println("Here is the traceback: " + pyx.toString()); } } public static void main ( String[] args ) { PythonInterpreter.initialize(System.getProperties(), null, new String[0]); PythonInterpreter interp = new PythonInterpreter(); runDodgyCode(interp, "undefined = 1/0"); runDodgyCode(interp, "for x [1,2]: print x"); runDodgyCode(interp, "[0,1,2][5]"); runDodgyCode(interp, "{1:2,3:4}[5]"); } } //============== CatchExceptions.java ===================== The same technique works for the PythonInterpreter eval() and execfile() methods. HTH, Alan. |
From: Jeff E. <jem...@fr...> - 2008-09-04 14:21:00
|
No, he means something like this: // codeString defines a Jython class implementating of a Java interface // and creates an instance of the class. interp.exec(codeString); AnInterface obj = (AnInterface)interp.get("obj").__tojava__(AnInterface.class); // Later. try { obj.someMethodWithBadJythonImplementation(); } catch (PyException pyEx) { // Does catching PyException here work? } Alan Kennedy wrote: > [David] > >> Can anyone suggest a way of trapping exceptions in runtime script execution ? >> > > Is this what you mean? > > //============== CatchExceptions.java ===================== > import org.python.core.*; > import org.python.util.PythonInterpreter; > > public class CatchExceptions > { > > public static void runDodgyCode ( PythonInterpreter interp, String > codeString ) > { > try > { > interp.exec(codeString); > } > catch (PyException pyx) > { > if (pyx.type == Py.IndexError) > System.err.println("This code >>>"+codeString+"<<< gave an > index error"); > if (pyx.type == Py.KeyError) > System.err.println("This code >>>"+codeString+"<<< gave a key error"); > if (pyx.type == Py.SyntaxError) > System.err.println("This code >>>"+codeString+"<<< gave a > syntax error"); > if (pyx.type == Py.ZeroDivisionError) > System.err.println("This code >>>"+codeString+"<<< gave a zero > division error"); > System.err.println("Here is the traceback: " + pyx.toString()); > } > } > > public static void main ( String[] args ) > { > PythonInterpreter.initialize(System.getProperties(), null, new String[0]); > PythonInterpreter interp = new PythonInterpreter(); > runDodgyCode(interp, "undefined = 1/0"); > runDodgyCode(interp, "for x [1,2]: print x"); > runDodgyCode(interp, "[0,1,2][5]"); > runDodgyCode(interp, "{1:2,3:4}[5]"); > } > > } > //============== CatchExceptions.java ===================== > > The same technique works for the PythonInterpreter eval() and > execfile() methods. > > HTH, > > Alan. > > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > Jython-users mailing list > Jyt...@li... > https://lists.sourceforge.net/lists/listinfo/jython-users > |
From: Alan K. <jyt...@xh...> - 2008-09-04 15:34:21
|
[Jeff] > No, he means something like this: > > // codeString defines a Jython class implementating of a Java interface > // and creates an instance of the class. OK, then here is the code that he needs. //============================================================ import org.python.core.*; import org.python.util.PythonInterpreter; public class CatchExceptions { public static Object compileCodeAndGetClass ( PythonInterpreter interp, String codeString, String targetClassName, String name) throws Exception { interp.exec(codeString); PyObject pyObj = (PyObject)interp.get(name).__call__(); if (pyObj == null) throw new Exception("Cannot find definition of '"+ name+"' class"); Class targetClass = Class.forName(targetClassName); Object jObj = pyObj.__tojava__(targetClass); if (jObj == Py.NoConversion) throw new Exception("Class '"+name+"' is not a " + "subclass of java class '"+targetClassName+"'"); return jObj; } public static void runDodgySubclass ( java.lang.Object o) { try { System.out.println("The String representation is: " + o.toString()); } catch (PyException pyx) { StringBuffer errMsg = new StringBuffer(); errMsg.append("Invocation of bad subclass gave a"); if (pyx.type == Py.IndexError) errMsg.append("n index error"); if (pyx.type == Py.KeyError) errMsg.append(" key error"); if (pyx.type == Py.SyntaxError) errMsg.append(" syntax error"); if (pyx.type == Py.ZeroDivisionError) errMsg.append(" zero division error"); System.err.println(errMsg.toString()); System.err.println("Here is the traceback: " + pyx.toString()); } } public static void main ( String[] args ) throws Exception { PythonInterpreter.initialize(System.getProperties(), null, new String[0]); PythonInterpreter interp = new PythonInterpreter(); StringBuffer codeString = new StringBuffer(); codeString.append("import java\n"); codeString.append("class MyObject(java.lang.Object):\n"); codeString.append(" def toString(self):\n"); codeString.append(" s = str(1/0)\n"); codeString.append(" return s\n"); java.lang.Object myPyObject = compileCodeAndGetClass( interp, codeString.toString(), "java.lang.Object", "MyObject"); runDodgySubclass(myPyObject); } } //============================================================ Alan. |
From: David G. <gr...@gm...> - 2008-09-05 11:16:03
|
Thanks, that all makes sense. Question.1 In the abstract base method definition in my Java baseclass (which the Jython class definition subclasses) do I have to declare that calling this method throws a Py Exception ? Or is it OK to just trap it when it happens ? Question 2 Is there any mileage in trying to parse the exception message to deduce what line in the code is dodgy or is that likely to be broken by future changes in the text format ? As far as I can tell PyException does not have actual fields for that information. PS has anyone had trouble posting to this list ? I posted this question a few times over the past few months and it never appeared until now. David |
From: Alan K. <jyt...@xh...> - 2008-09-05 12:38:20
|
[David] > Question.1 > > In the abstract base method definition in my Java baseclass (which the > Jython class definition subclasses) do I have to declare that calling > this method throws a Py Exception ? > Or is it OK to just trap it when it happens ? The code I posted worked just fine without it. Have you tried it? I.e. declaring it with and without? [David] > Question 2 > > Is there any mileage in trying to parse the exception message to > deduce what line in the code is dodgy or is that likely to be broken > by future changes in the text format ? > As far as I can tell PyException does not have actual fields for that > information. PyException has a PyTraceback field, called "traceback", which contains what you need, and is documented here http://www.jython.org/docs/javadoc/org/python/core/PyTraceback.html http://www.jython.org/docs/javadoc/org/python/core/PyException.html Alan. |