- A Concurrent Affair - https://www.concurrentaffair.org -

Another Bugfix for Smart Run

A while ago, I introduced what was supposed to be a “Smart Run” feature [1], a simpler way of running Java programs, ACM Java Task Force programs, and applets. It sort of worked, but it has been difficult to get it right [2]: The code is concatenated in an ugly manner and interpreted, but since it’s still Java with its type system, I sort of get all the problems but none of the benefits of interpretation.

Now Paul Ezust, Professor of Mathematics and Computer Science at Suffolk University, has notified me of another problem [3]: If the class a user is attempting to run is not marked public then an exception is thrown.

With “Smart Run”, the code to start the program is a lot more complicated. DrJava needs to determine whether a program is an applet, and if it isn’t, it needs to check if it is an ACM Java Task Force program. In the last two situations, the main method is then invoked using reflection (come to think of it, I could probably do this without reflection, too… I should try that).

If the class isn’t public, then Method [4].invoke will throw an IllegalAccessException [5] unless I call setAccessible(true) first. Now I do that, and I also handle the other exceptions better.

Here’s the concatenated command. Unwieldy, hm? I wish Java had multiline quotes.

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    String [6] command =
      "'{' boolean isProgram = false; boolean isApplet = false; Class c = {0}.class;\n" +
      // cannot use Class.forName, doesn't work in Interactions Pane (see bug #1080869)
      "while(c != null) '{'\n" +
      "  if ("acm.program.Program".equals(c.getName())) '{' isProgram = true; break; '}'\n" +
      "  c = c.getSuperclass();\n" +
      "'}'\n" +
      "if (!isProgram) '{'\n" +
      "  try '{'\n" +
      // if this doesn't throw, {0} is a subclass of Applet
      "    {0}.class.asSubclass(java.applet.Applet.class);\n" +
      "    isApplet = true;\n" +
      "  '}' catch(ClassCastException cce) '{' '}'\n" +
      "'}'\n" +
      "if (isApplet) '{'\n" +
      "  edu.rice.cs.plt.swing.SwingUtil.showApplet(java.applet.Applet.class.cast(new {0}({1})), 400, 300);\n" +
      "'}'\n" +
      "else '{'" +
      "  java.lang.reflect.Method m = null;\n" +
      "  try '{'\n" +
      "    m = {0}.class.getMethod("main", java.lang.String[].class);\n" +
      "    if (!m.getReturnType().equals(void.class)) throw new java.lang.NoSuchMethodException();\n" +
      "  '}'\n" +
      "  catch (java.lang.NoSuchMethodException e) '{'\n" +
      "    throw new java.lang.NoSuchMethodError("main");\n" +
      "  '}'\n" +
      "  String[] args = new String[]'{'{1}'}';\n" +
      "  if (isProgram) '{'\n" +
      "    String[] newArgs = new String[args.length+1];\n" +
      "    newArgs[0] = "code={0}";\n" +
      "    System.arraycopy(args, 0, newArgs, 1, args.length);\n" +
      "    args = newArgs;\n" +
      "  '}'\n" +
      "  try '{'" +
      "    m.setAccessible(true);\n" +
      "    m.invoke(null, new Object[] '{' args '}');\n" +
      "  '}' catch(SecurityException se) '{'\n" +
      "    System.err.println("Error [7]: Please turn off 'Smart Run' or use 'java' command instead of 'run'.");\n" +
      "  '}' catch(IllegalAccessException iae) '{'\n" +
      "    System.err.println("Error [7]: Please turn off 'Smart Run' or use 'java' command instead of 'run'.");\n" +
      "  '}' catch(java.lang.reflect.InvocationTargetException ite) '{'\n" +
      "    if (ite.getCause()!=null) throw ite.getCause(); else\n" +
      "    System.err.println("Error [7]: Please turn off 'Smart Run' or use 'java' command instead of 'run'.");\n" +
      "'}' '}' '}'";

I should try to rewrite this as Java code that doesn’t get interpreted in our Interactions Pane, but that actually gets statically compiled.

The bugfix is currently only available in our (more or less) DrJava weekly jar [8].

[9] [10]Share [11]