private static void endInterpreter(String contextId) throws EvalError { Interpreter i = interpreters.get(contextId); if (i == null) return; i.eval("clear();"); // can't hurt to tell bsh to clean up internally interpreters.remove(contextId); // now wait for GC Log.log("Destroyed context: " + contextId + " (" + i + ")"); }
/** * Runs a BeanShell script. Errors are passed to the caller. * * <p>If the <code>in</code> parameter is non-null, the script is read from that stream; otherwise * it is read from the file identified by <code>path</code> . * * <p>The <code>scriptPath</code> BeanShell variable is set to the path name of the script. * * @param path The script file's VFS path. * @param in The reader to read the script from, or <code>null</code> . * @param namespace The namespace to run the script in. * @exception Exception instances are thrown when various BeanShell errors occur * @since jEdit 4.2pre5 */ public void _runScript(String path, Reader in, NameSpace namespace) throws Exception { log.info("Running script " + path); Interpreter interp = createInterpreter(namespace); try { if (in == null) { in = res.getResourceAsReader(path); } setupDefaultVariables(namespace); interp.set("scriptPath", path); running = true; interp.eval(in, namespace, path); } catch (Exception e) { unwrapException(e); } finally { running = false; try { // no need to do this for macros! if (namespace == global) { resetDefaultVariables(namespace); interp.unset("scriptPath"); } } catch (EvalError e) { // do nothing } } } // }}}
private String backgroundColour(String type) { LispExpr e = interpreter.getGlobalExpr(type); if (!(e instanceof LispString)) { e = interpreter.getGlobalExpr("text-background-colour"); if (!(e instanceof LispString)) { return "white"; } } return ((LispString) e).toString(); }
private void parseAndLoadInputs(String inputs) throws Exception { String inputTokens[] = inputs.split("\\s+"); for (int i = 0; i < inputTokens.length; i++) { String token = inputTokens[i]; if (token.equals("")) { continue; } else if (token.equals("true")) { _interpreter.boolStack().push(true); _interpreter.inputStack().push(true); } else if (token.equals("false")) { _interpreter.boolStack().push(false); _interpreter.inputStack().push(false); } else if (token.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")) { if (token.indexOf('.') != -1) { _interpreter.floatStack().push(Float.parseFloat(token)); _interpreter.inputStack().push(Float.parseFloat(token)); } else { _interpreter.intStack().push(Integer.parseInt(token)); _interpreter.inputStack().push(Integer.parseInt(token)); } } else { throw new Exception( "Inputs must be of type int, float, or boolean. \"" + token + "\" is none of these."); } } }
public static void main(String argv[]) { // basically, if a command-line parameter is supplied // then assume it is a file name and execute it as // a simpular program without using the GUI at all. if (argv.length == 0) { // no command-line parameters, so use GUI. InterpreterFrame f = new InterpreterFrame(); } else if (argv[0].equals("-no-gui")) { // run interpreter without GUI! // setup new argument list for original // Main method String[] newargv = new String[argv.length - 1]; for (int i = 1; i != argv.length; ++i) { newargv[i - 1] = argv[i]; } Interpreter.main(newargv); } else { // run interpreter with GUI, but // load requested file. InterpreterFrame f = new InterpreterFrame(); // load file into text view f.textView.setText(f.physReadTextFile(new File(argv[0]))); // update status f.statusView.setText(" Loaded file \"" + argv[0] + "\"."); // reset dirty bit f.dirty = false; } }
public static void main(String[] args) throws Exception { if (args.length < 1) { System.out.println("java ScalaInterpretNIO [script file]"); return; } FileChannel fc = new FileInputStream(args[0]).getChannel(); MappedByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); CharBuffer chb = Charset.defaultCharset().decode(buffer); Interpreter p = new Interpreter(new Settings()); p.interpret(chb.toString()); p.close(); }
Object evalScript( String script, StringBuffer scriptOutput, boolean captureOutErr, HttpServletRequest request, HttpServletResponse response) throws EvalError { // Create a PrintStream to capture output ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream pout = new PrintStream(baos); // Create an interpreter instance with a null inputstream, // the capture out/err stream, non-interactive Interpreter bsh = new Interpreter(null, pout, pout, false); // set up interpreter bsh.set("bsh.httpServletRequest", request); bsh.set("bsh.httpServletResponse", response); // Eval the text, gathering the return value or any error. Object result = null; String error = null; PrintStream sout = System.out; PrintStream serr = System.err; if (captureOutErr) { System.setOut(pout); System.setErr(pout); } try { // Eval the user text result = bsh.eval(script); } finally { if (captureOutErr) { System.setOut(sout); System.setErr(serr); } } pout.flush(); scriptOutput.append(baos.toString()); return result; }
static String getBshVersion() { if (bshVersion != null) return bshVersion; /* We have included a getVersion() command to detect the version of bsh. If bsh is packaged in the WAR file it could access it directly as a bsh command. But if bsh is in the app server's classpath it won't see it here, so we will source it directly. This command works around the lack of a coherent version number in the early versions. */ Interpreter bsh = new Interpreter(); try { bsh.eval(new InputStreamReader(BshServlet.class.getResource("getVersion.bsh").openStream())); bshVersion = (String) bsh.eval("getVersion()"); } catch (Exception e) { bshVersion = "BeanShell: unknown version"; } return bshVersion; }
public static void main(String args[]) throws Exception { Yylex l = null; parser p; Interpreter I; try { if (args.length == 0) l = new Yylex(System.in); else l = new Yylex(new FileReader(args[0])); } catch (FileNotFoundException e) { System.err.println("Error: File not found: " + args[0]); System.exit(1); } p = new parser(l); /* The default parser is the first-defined entry point. */ /* You may want to change this. Other options are: */ /* */ try { calc.Absyn.Exp parse_tree = p.pExp(); I = new Interpreter(); // I.eval(parse_tree) ; System.out.println(I.eval(parse_tree)); /*System.out.println(); System.out.println("Parse Succesful!"); System.out.println(); System.out.println("[Abstract Syntax]"); System.out.println(); System.out.println(PrettyPrinter.show(parse_tree)); System.out.println(); System.out.println("[Linearized Tree]"); System.out.println(); System.out.println(PrettyPrinter.print(parse_tree)); */ } catch (Throwable e) { System.err.println( "At line " + String.valueOf(l.line_num()) + ", near \"" + l.buff() + "\" :"); System.err.println(" " + e.getMessage()); System.exit(1); } }
/** * Evaluates the specified BeanShell expression. Unlike <code>eval()</code> , this method passes * any exceptions to the caller. * * @param namespace The namespace * @param command The expression * @return Description of the Return Value * @exception Exception instances are thrown when various BeanShell errors occur * @since jEdit 3.2pre7 */ public Object _eval(NameSpace namespace, String command) throws Exception { Interpreter interp = createInterpreter(namespace); try { setupDefaultVariables(namespace); if (log.isDebugEnabled()) { log.debug("Running script: " + command); } return interp.eval(command); } catch (Exception e) { unwrapException(e); // never called return null; } finally { // try { resetDefaultVariables(namespace); // } // catch (UtilEvalError e) { // do nothing // } } } // }}}
public void run(String path) { if (path == null || path.equals("")) path = showDialog(); if (path == null) return; openingStartupMacrosInEditor = path.indexOf("StartupMacros") != -1; String text = open(path); if (text != null) { String functions = Interpreter.getAdditionalFunctions(); if (functions != null) { if (!(text.endsWith("\n") || functions.startsWith("\n"))) text = text + "\n" + functions; else text = text + functions; } install(text); } }
private void checkForInputIn(String programString) { String added = ""; String numstr = ""; int index = 0; int numindex = 0; int spaceindex = 0; int parenindex = 0; int endindex = 0; while (true) { index = programString.indexOf("input.in"); if (index == -1) break; // System.out.println(programString + " " + index); numindex = index + 8; if (!Character.isDigit(programString.charAt(numindex))) { programString = programString.substring(numindex); continue; } spaceindex = programString.indexOf(' ', numindex); parenindex = programString.indexOf(')', numindex); if (spaceindex == -1) endindex = parenindex; else if (parenindex == -1) endindex = spaceindex; else endindex = Math.min(spaceindex, parenindex); numstr = programString.substring(numindex, endindex); // Check for doubles in added if (added.indexOf(" " + numstr + " ") == -1) { added = added + " " + numstr + " "; _interpreter.AddInstruction("input.in" + numstr, new InputInN(Integer.parseInt(numstr))); } programString = programString.substring(numindex); } }
public InterpreterFrame() { super("Simple Lisp Interpreter"); // Create the menu menubar = buildMenuBar(); setJMenuBar(menubar); // Create the toolbar toolbar = buildToolBar(); // disable cut and copy actions cutAction.setEnabled(false); copyAction.setEnabled(false); // Setup text area for editing source code // and setup document listener so interpreter // is notified when current file modified and // when the cursor is moved. textView = buildEditor(); textView.getDocument().addDocumentListener(this); textView.addCaretListener(this); // set default key bindings bindKeyToCommand("ctrl C", "(buffer-copy)"); bindKeyToCommand("ctrl X", "(buffer-cut)"); bindKeyToCommand("ctrl V", "(buffer-paste)"); bindKeyToCommand("ctrl E", "(buffer-eval)"); bindKeyToCommand("ctrl O", "(file-open)"); bindKeyToCommand("ctrl S", "(file-save)"); bindKeyToCommand("ctrl Q", "(exit)"); // Give text view scrolling capability Border border = BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder(3, 3, 3, 3), BorderFactory.createLineBorder(Color.gray)); JScrollPane topSplit = addScrollers(textView); topSplit.setBorder(border); // Create tabbed pane for console/problems consoleView = makeConsoleArea(10, 50, true); problemsView = makeConsoleArea(10, 50, false); tabbedPane = buildProblemsConsole(); // Plug the editor and problems/console together // using a split pane. This allows one to change // their relative size using the split-bar in // between them. splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topSplit, tabbedPane); // Create status bar statusView = new JLabel(" Status"); lineNumberView = new JLabel("0:0"); statusbar = buildStatusBar(); // Now, create the outer panel which holds // everything together outerpanel = new JPanel(); outerpanel.setLayout(new BorderLayout()); outerpanel.add(toolbar, BorderLayout.PAGE_START); outerpanel.add(splitPane, BorderLayout.CENTER); outerpanel.add(statusbar, BorderLayout.SOUTH); getContentPane().add(outerpanel); // tell frame to fire a WindowsListener event // but not to close when "x" button clicked. setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); addWindowListener(this); // set minimised icon to use setIconImage(makeImageIcon("spi.png").getImage()); // setup additional internal functions InternalFunctions.setup_internals(interpreter, this); // set default window size Component top = splitPane.getTopComponent(); Component bottom = splitPane.getBottomComponent(); top.setPreferredSize(new Dimension(100, 400)); bottom.setPreferredSize(new Dimension(100, 200)); pack(); // load + run user configuration file (if there is one) String homedir = System.getProperty("user.home"); try { interpreter.load(homedir + "/.simplelisp"); } catch (FileNotFoundException e) { // do nothing if file does not exist! System.out.println("Didn't find \"" + homedir + "/.simplelisp\""); } textView.grabFocus(); setVisible(true); // redirect all I/O to problems/console redirectIO(); // start highlighter thread highlighter = new DisplayThread(250); highlighter.setDaemon(true); highlighter.start(); }
/** * Initializes an InspectorInput. The file should be organized as follows: * * <p>1 Program to execute 2 Execution limit 3 Integer, float, or boolean inputs 4 Available * instructions. This is only used for creating random code with code.rand or exec.rand * * @param inFile The file to input from. */ private void InitInspectorInput(File inFile) throws Exception { _interpreter = new Interpreter(); // Read fileString String fileString = Params.ReadFileString(inFile); // Get programString int indexNewline = fileString.indexOf("\n"); String programString = fileString.substring(0, indexNewline).trim(); fileString = fileString.substring(indexNewline + 1); // Get _executionLimit indexNewline = fileString.indexOf("\n"); if (indexNewline != -1) { String limitString = fileString.substring(0, indexNewline).trim(); _executionLimit = Integer.parseInt(limitString); fileString = fileString.substring(indexNewline + 1); } else { // If here, no inputs to be pushed were included _executionLimit = Integer.parseInt(fileString); fileString = ""; } // Get inputs and push them onto correct stacks. If fileString = "" // at this point, then can still do the following with correct result. indexNewline = fileString.indexOf("\n"); if (indexNewline != -1) { String inputsString = fileString.substring(0, indexNewline).trim(); fileString = fileString.substring(indexNewline + 1); // Parse the inputs and load them into the interpreter parseAndLoadInputs(inputsString); } else { parseAndLoadInputs(fileString); fileString = ""; } // Get the available instructions for random code generation indexNewline = fileString.indexOf("\n"); if (!fileString.trim().equals("")) { _interpreter.SetInstructions(new Program(_interpreter, fileString.trim())); } // Check for input.inN instructions checkForInputIn(programString); // Add random integer and float parameters _interpreter._minRandomInt = -10; _interpreter._maxRandomInt = 10; _interpreter._randomIntResolution = 1; _interpreter._minRandomFloat = -10.0f; _interpreter._maxRandomFloat = 10.0f; _interpreter._randomFloatResolution = 0.01f; _interpreter._maxRandomCodeSize = 50; // Load the program _program = new Program(_interpreter, programString); _interpreter.LoadProgram(_program); // Initializes program }
/** * Parse the BSHBlock for for the class definition and generate the class using ClassGenerator. */ public static Class generateClassImpl( String name, Modifiers modifiers, Class[] interfaces, Class superClass, BSHBlock block, boolean isInterface, CallStack callstack, Interpreter interpreter) throws EvalError { // Scripting classes currently requires accessibility // This can be eliminated with a bit more work. try { Capabilities.setAccessibility(true); } catch (Capabilities.Unavailable e) { throw new EvalError( "Defining classes currently requires reflective Accessibility.", block, callstack); } NameSpace enclosingNameSpace = callstack.top(); String packageName = enclosingNameSpace.getPackage(); String className = enclosingNameSpace.isClass ? (enclosingNameSpace.getName() + "$" + name) : name; String fqClassName = packageName == null ? className : packageName + "." + className; BshClassManager bcm = interpreter.getClassManager(); // Race condition here... bcm.definingClass(fqClassName); // Create the class static namespace NameSpace classStaticNameSpace = new NameSpace(enclosingNameSpace, className); classStaticNameSpace.isClass = true; callstack.push(classStaticNameSpace); // Evaluate any inner class class definitions in the block // effectively recursively call this method for contained classes first block.evalBlock(callstack, interpreter, true /*override*/, ClassNodeFilter.CLASSCLASSES); // Generate the type for our class Variable[] variables = getDeclaredVariables(block, callstack, interpreter, packageName); DelayedEvalBshMethod[] methods = getDeclaredMethods(block, callstack, interpreter, packageName); ClassGeneratorUtil classGenerator = new ClassGeneratorUtil( modifiers, className, packageName, superClass, interfaces, variables, methods, classStaticNameSpace, isInterface); byte[] code = classGenerator.generateClass(); // if debug, write out the class file to debugClasses directory if (DEBUG_DIR != null) try { FileOutputStream out = new FileOutputStream(DEBUG_DIR + '/' + className + ".class"); out.write(code); out.close(); } catch (IOException e) { throw new IllegalStateException( "cannot create file " + DEBUG_DIR + '/' + className + ".class", e); } // Define the new class in the classloader Class genClass = bcm.defineClass(fqClassName, code); // import the unq name into parent enclosingNameSpace.importClass(fqClassName.replace('$', '.')); try { classStaticNameSpace.setLocalVariable( ClassGeneratorUtil.BSHINIT, block, false /*strictJava*/); } catch (UtilEvalError e) { throw new InterpreterError("unable to init static: " + e); } // Give the static space its class static import // important to do this after all classes are defined classStaticNameSpace.setClassStatic(genClass); // evaluate the static portion of the block in the static space block.evalBlock(callstack, interpreter, true /*override*/, ClassNodeFilter.CLASSSTATIC); callstack.pop(); if (!genClass.isInterface()) { // Set the static bsh This callback String bshStaticFieldName = ClassGeneratorUtil.BSHSTATIC + className; try { LHS lhs = Reflect.getLHSStaticField(genClass, bshStaticFieldName); lhs.assign(classStaticNameSpace.getThis(interpreter), false /*strict*/); } catch (Exception e) { throw new InterpreterError("Error in class gen setup: " + e); } } bcm.doneDefiningClass(fqClassName); return genClass; }
public void installLibrary(String path) { String text = open(path); if (text != null) Interpreter.setAdditionalFunctions(text); }
private static Interpreter getInterpreter(String contextId) throws EvalError { // Get the appropriate interpreter Interpreter i = null; boolean createdInterp = false; synchronized (interpreters) { // serialize two gets of the same name i = interpreters.get(contextId); if (i == null) { i = new Interpreter(); interpreters.put(contextId, i); createdInterp = true; } } if (createdInterp) { Log.log("Created context: " + contextId + " (" + i + ")"); // Now configure stdin and stdout to capture 10k of content // Store references to the circular buffers within the interpreter itself. // This provides a nice place to store them plus theoretically allows // advanced use from within the bsh environment. // On Windows print() outputs \r\n but in XQuery that's normalized to \n // so the 10k of Java buffer may produce less than 10k of content in XQuery! OutputStream circularOutput = new CircularByteArrayOutputStream(10240); PrintStream printOutput = new PrintStream(circularOutput); i.setOut(printOutput); i.set("mljamout", circularOutput); OutputStream circularError = new CircularByteArrayOutputStream(10240); PrintStream printError = new PrintStream(circularError); i.setErr(printError); i.set("mljamerr", circularError); // Capture the built-in System.out and System.err also. // (Commented out since System appears global, can't do per interpreter.) // i.set("mljamprintout", printOutput); // i.set("mljamprinterr", printError); // i.eval("System.setOut(mljamprintout);"); // i.eval("System.setErr(mljamprinterr);"); // Need to expose hexdecode() and base64decode() built-in functions i.eval("hexdecode(String s) { return com.xqdev.jam.MLJAM.hexDecode(s); }"); i.eval("base64decode(String s) { return com.xqdev.jam.MLJAM.base64Decode(s); }"); // Let's tell the context what its id is i.set("mljamid", contextId); } // Update the last accessed time, used for cleaning i.set("mljamlast", System.currentTimeMillis()); // If it's been long enough, go snooping for stale contexts if (System.currentTimeMillis() > lastClean + CLEAN_INTERVAL) { Log.log("Initiated periodic scan for stale context objects"); lastClean = System.currentTimeMillis(); Iterator<Interpreter> itr = interpreters.values().iterator(); while (itr.hasNext()) { Interpreter interp = itr.next(); Long last = (Long) interp.get("mljamlast"); if (System.currentTimeMillis() > last + STALE_TIMEOUT) { itr.remove(); Log.log("Staled context: " + interp.get("mljamid") + " (" + interp + ")"); } else if ((System.currentTimeMillis() > last + TEMP_STALE_TIMEOUT) && ("" + interp.get("mljamid")).startsWith("temp:")) { itr.remove(); Log.log("Staled temp context: " + interp.get("mljamid") + " (" + interp + ")"); } } } return i; }
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { try { // A good request looks like /mljam/contextid/verb?name=varname // The extra path info includes the context id and verb String extra = req.getPathInfo(); // "/contextid/verb" if (extra == null || extra.equals("")) { throw new ClientProblemException( "Request requires a context id and verb in its extra path info"); } String[] parts = extra.split("/"); // { "", "contextid", "verb" } if (parts.length < 2) { throw new ClientProblemException( "Request requires a context id and verb in its extra path info"); } else if (parts.length < 3) { throw new ClientProblemException("Request requires a verb in its extra path info"); } String contextId = parts[1]; String verb = parts[2]; String method = req.getMethod(); if (method.equalsIgnoreCase("get")) { // We have three GET verbs: get, get-stdout, get-stderr. // These are all idempotent, while the POST verbs aren't. The get // verb accept a "name" query string parameter. The get verb returns // either XQuery to evaluate (indicated by x-marklogic/xquery content type) // or a raw binary (indicated by an application/binary-encoded content type). if (verb.equalsIgnoreCase("get")) { String name = req.getParameter("name"); if (name == null || name.equals("")) { throw new ClientProblemException("The get verb requires a name parameter"); } Interpreter i = getInterpreter(contextId); Object o = i.get(name); if (o instanceof byte[]) { sendBinaryResponse(res, (byte[]) o); } else if (o instanceof String) { sendStringResponse(res, (String) o); } else { sendXQueryResponse(res, o); } } else if (verb.equalsIgnoreCase("get-stdout")) { Interpreter i = getInterpreter(contextId); i.getOut().flush(); CircularByteArrayOutputStream circ = (CircularByteArrayOutputStream) i.get("mljamout"); if (circ != null) { sendStringResponse(res, circ.toString()); circ.reset(); } else { throw new ServerProblemException("Could not fetch mljamout from interpreter context"); } } else if (verb.equalsIgnoreCase("get-stderr")) { Interpreter i = getInterpreter(contextId); i.getErr().flush(); CircularByteArrayOutputStream circ = (CircularByteArrayOutputStream) i.get("mljamerr"); if (circ != null) { sendStringResponse(res, circ.toString()); circ.reset(); } else { throw new ServerProblemException("Could not fetch mljamerr from interpreter context"); } } else { throw new ClientProblemException("Unrecognized GET verb: " + verb); } } else if (method.equalsIgnoreCase("post")) { // We have six POST verbs: eval, unset, end, source, set-string, and set-binary. // These are POST verbs because they aren't idempotent. // The set-string, set-binary, unset, and source verbs accept a "name" // query string parameter. The set-string and set-binary verbs accept // a value in their post body. The eval verb accepts code in its post body. if (verb.equalsIgnoreCase("set-string")) { String name = req.getParameter("name"); if (name == null || name.equals("")) { throw new ClientProblemException("The set-string verb requires a name parameter"); } String body = getBody(req); // a value of "" is legit Interpreter i = getInterpreter(contextId); i.unset(name); i.set(name, body); sendNoResponse(res); } else if (verb.equalsIgnoreCase("set-binary")) { String name = req.getParameter("name"); if (name == null || name.equals("")) { throw new ClientProblemException("The set-binary verb requires a name parameter"); } String body = getBody(req); // a value of "" is legit byte[] bodyBytes = hexDecode(body); // later could do this streaming for speed Interpreter i = getInterpreter(contextId); i.unset(name); i.set(name, bodyBytes); sendNoResponse(res); } else if (verb.equalsIgnoreCase("eval")) { String body = getBody(req); if (body == null || body.equals("")) { throw new ClientProblemException( "The eval verb requires a post body containing code to eval"); } Interpreter i = getInterpreter(contextId); i.eval(body); sendNoResponse(res); } else if (verb.equalsIgnoreCase("eval-get")) { String body = getBody(req); if (body == null || body.equals("")) { throw new ClientProblemException( "The eval-get verb requires a post body containing code to eval"); } Interpreter i = getInterpreter(contextId); Object o = i.eval(body); if (o instanceof byte[]) { sendBinaryResponse(res, (byte[]) o); } else if (o instanceof String) { sendStringResponse(res, (String) o); } else { sendXQueryResponse(res, o); } } else if (verb.equalsIgnoreCase("unset")) { String name = req.getParameter("name"); if (name == null || name.equals("")) { throw new ClientProblemException("The unset verb requires a name parameter"); } Interpreter i = getInterpreter(contextId); i.unset(name); sendNoResponse(res); } else if (verb.equalsIgnoreCase("end")) { endInterpreter(contextId); sendNoResponse(res); } else if (verb.equalsIgnoreCase("source")) { String name = req.getParameter("name"); if (name == null || name.equals("")) { throw new ClientProblemException("The source verb requires a name parameter"); } Interpreter i = getInterpreter(contextId); i.source(name); sendNoResponse(res); } else { throw new ClientProblemException("Unrecognized POST verb: " + verb); } } } catch (TargetError e) { Throwable target = e.getTarget(); Log.log(e); Log.log("Target: " + target); sendServerProblemResponse( res, target.getClass().getName() + ": " + target.getMessage() + " when executing Java code: " + e.getErrorText()); // include full trace? } catch (EvalError e) { Log.log(e); sendServerProblemResponse( res, e.getClass().getName() + ": " + e.getMessage()); // include full trace? } catch (ClientProblemException e) { Log.log(e); sendClientProblemResponse(res, e.getMessage()); } catch (ServerProblemException e) { Log.log(e); sendServerProblemResponse(res, e.getMessage()); } }