Skip to content

Commit 482d47c

Browse files
author
mgricken
committed
Bugfix for 2674112: Error loading class in Interpreter
Now prints out the error: Static Error: Class '$1' cannot access its superinterface 'UnaryFun'. Make sure 'UnaryFun' is a public interface. I think this is as good as it can get since we can't load classes that aren't accessible as per 5.4.4. Note: I put JavaInterpreterTest back, but there are two test cases that fail, so I commented them out. The bug 2974931: Boolean Short-Circuiting Doesn't Work needs to be addressed. git-svn-id: file:///tmp/test-svn/trunk@5198 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent a139a9e commit 482d47c

File tree

7 files changed

+735
-400
lines changed

7 files changed

+735
-400
lines changed

drjava/lib/dynamicjava-base.jar

27.6 KB
Binary file not shown.
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/*BEGIN_COPYRIGHT_BLOCK
2+
*
3+
* Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions are met:
8+
* * Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in the
12+
* documentation and/or other materials provided with the distribution.
13+
* * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
14+
* names of its contributors may be used to endorse or promote products
15+
* derived from this software without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*
29+
* This software is Open Source Initiative approved Open Source Software.
30+
* Open Source Initative Approved is a trademark of the Open Source Initiative.
31+
*
32+
* This file is part of DrJava. Download the current version of this project
33+
* from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
34+
*
35+
* END_COPYRIGHT_BLOCK*/
36+
37+
package edu.rice.cs.drjava.model.repl;
38+
39+
import edu.rice.cs.drjava.DrJavaTestCase;
40+
import edu.rice.cs.drjava.model.*;
41+
import edu.rice.cs.drjava.model.repl.newjvm.MainJVM;
42+
43+
import edu.rice.cs.util.FileOpenSelector;
44+
import edu.rice.cs.util.Log;
45+
import edu.rice.cs.util.swing.Utilities;
46+
import edu.rice.cs.util.text.ConsoleDocument;
47+
import edu.rice.cs.util.text.EditDocumentException;
48+
import javax.swing.text.BadLocationException;
49+
import edu.rice.cs.plt.tuple.Pair;
50+
51+
52+
import edu.rice.cs.drjava.model.repl.newjvm.*;
53+
import edu.rice.cs.drjava.DrJavaTestCase;
54+
55+
import edu.rice.cs.plt.tuple.OptionVisitor;
56+
import edu.rice.cs.plt.reflect.ReflectUtil;
57+
import edu.rice.cs.plt.text.TextUtil;
58+
59+
import edu.rice.cs.dynamicjava.Options;
60+
import edu.rice.cs.dynamicjava.interpreter.*;
61+
import edu.rice.cs.dynamicjava.symbol.*;
62+
import edu.rice.cs.dynamicjava.symbol.type.Type;
63+
64+
import java.io.File;
65+
import java.io.IOException;
66+
import java.io.StringWriter;
67+
import java.io.PrintWriter;
68+
import java.util.List;
69+
import java.util.ArrayList;
70+
71+
import java.rmi.RemoteException;
72+
73+
import edu.rice.cs.drjava.model.GlobalModelTestCase;
74+
75+
import static edu.rice.cs.drjava.model.repl.InteractionsModelTest.TestInteractionsModel;
76+
import static edu.rice.cs.drjava.model.repl.InteractionsModelTest.IncompleteInputInteractionsModel;
77+
78+
/** Tests errors in an InteractionsModel.
79+
* @version $Id$
80+
*/
81+
public final class InteractionsModelErrorTest extends GlobalModelTestCase {
82+
protected static final String UNARY_FUN_NON_PUBLIC_INTERFACE_TEXT =
83+
"interface UnaryFun {\n"+
84+
" public Object apply(final Object arg);\n"+
85+
"}";
86+
protected static final String UNARY_FUN_PUBLIC_INTERFACE_TEXT =
87+
"public interface UnaryFun {\n"+
88+
" public Object apply(final Object arg);\n"+
89+
"}";
90+
91+
protected static final String UNARY_FUN_NON_PUBLIC_CLASS_TEXT =
92+
"abstract class UnaryFun {\n"+
93+
" public abstract Object apply(final Object arg);\n"+
94+
"}";
95+
protected static final String UNARY_FUN_PUBLIC_CLASS_TEXT =
96+
"public abstract class UnaryFun {\n"+
97+
" public abstract Object apply(final Object arg);\n"+
98+
"}";
99+
100+
private volatile InteractionsPaneOptions _interpreterOptions;
101+
private volatile Interpreter _interpreter;
102+
private volatile ClassPathManager _classPathManager;
103+
private volatile ClassLoader _interpreterLoader;
104+
105+
private static Log _log = new Log("InteractionsModelErrorTest.txt", false);
106+
107+
public InteractionsModelErrorTest() {
108+
super();
109+
110+
_classPathManager = new ClassPathManager(ReflectUtil.SYSTEM_CLASS_PATH);
111+
_interpreterLoader = _classPathManager.makeClassLoader(null);
112+
113+
// _interpreterOptions = Options.DEFAULT;
114+
_interpreterOptions = new InteractionsPaneOptions();
115+
_interpreter = new Interpreter(_interpreterOptions, _interpreterLoader);
116+
}
117+
118+
/** Asserts that the results of interpreting the first of each
119+
* Pair is equal to the second.
120+
* @param cases an array of Pairs
121+
*/
122+
private void tester(Pair<String,Object>[] cases) throws InterpreterException {
123+
for (int i = 0; i < cases.length; i++) {
124+
Object out = interpretDirectly(cases[i].first());
125+
assertEquals(cases[i].first() + " interpretation wrong!", cases[i].second(), out);
126+
}
127+
}
128+
129+
private Object interpretDirectly(String s) throws InterpreterException {
130+
return _interpreter.interpret(s).apply(new OptionVisitor<Object, Object>() {
131+
public Object forNone() { return null; }
132+
public Object forSome(Object obj) { return obj; }
133+
});
134+
}
135+
136+
protected String _name() {
137+
return "compiler=" + _model.getCompilerModel().getActiveCompiler().getName() + ": ";
138+
}
139+
140+
/** Tests that we get the correct 'cannot access its superinterface' error for non-public classes. */
141+
@SuppressWarnings("unchecked")
142+
public void testInterpretExtendNonPublic()
143+
throws BadLocationException, IOException, InterruptedException, InterpreterException {
144+
_log.log("testInterpretExtendNonPublic started");
145+
146+
OpenDefinitionsDocument doc = setupDocument(UNARY_FUN_NON_PUBLIC_INTERFACE_TEXT);
147+
final File file = tempFile();
148+
saveFile(doc, new FileSelector(file));
149+
CompileShouldSucceedListener listener = new CompileShouldSucceedListener();
150+
_model.addListener(listener);
151+
listener.compile(doc);
152+
if (_model.getCompilerModel().getNumErrors() > 0) {
153+
fail("compile failed: " + getCompilerErrorString());
154+
}
155+
listener.checkCompileOccurred();
156+
_model.removeListener(listener);
157+
assertCompileErrorsPresent(_name(), false);
158+
159+
// Make sure .class exists
160+
File compiled = classForJava(file, "UnaryFun");
161+
assertTrue(_name() + "Class file should exist after compile", compiled.exists());
162+
163+
_classPathManager.addBuildDirectoryCP(compiled.getParentFile());
164+
165+
try {
166+
_interpreter.interpret("UnaryFun f = new UnaryFun() { Object apply(Object arg) { return (Integer)arg * (Integer)arg; }}");
167+
fail("Should fail with 'cannot access its superinterface' exception.");
168+
}
169+
catch(edu.rice.cs.dynamicjava.interpreter.CheckerException ce) {
170+
assertTrue(ce.getMessage().indexOf("cannot access its superinterface")>=0);
171+
}
172+
}
173+
174+
/** Tests that we don't get an error for public classes. */
175+
@SuppressWarnings("unchecked")
176+
public void testInterpretExtendPublic()
177+
throws BadLocationException, IOException, InterruptedException, InterpreterException {
178+
_log.log("testInterpretExtendPublic started");
179+
180+
OpenDefinitionsDocument doc = setupDocument(UNARY_FUN_PUBLIC_INTERFACE_TEXT);
181+
final File file = createFile("UnaryFun.java");
182+
saveFile(doc, new FileSelector(file));
183+
CompileShouldSucceedListener listener = new CompileShouldSucceedListener();
184+
_model.addListener(listener);
185+
listener.compile(doc);
186+
if (_model.getCompilerModel().getNumErrors() > 0) {
187+
fail("compile failed: " + getCompilerErrorString());
188+
}
189+
listener.checkCompileOccurred();
190+
_model.removeListener(listener);
191+
assertCompileErrorsPresent(_name(), false);
192+
193+
// Make sure .class exists
194+
File compiled = classForJava(file, "UnaryFun");
195+
assertTrue(_name() + "Class file should exist after compile", compiled.exists());
196+
197+
_classPathManager.addBuildDirectoryCP(compiled.getParentFile());
198+
199+
_interpreter.interpret("UnaryFun f = new UnaryFun() { Object apply(Object arg) { return (Integer)arg * (Integer)arg; }}");
200+
}
201+
202+
/** Tests that we get the correct 'cannot access its superinterface' error for non-public classes. */
203+
@SuppressWarnings("unchecked")
204+
public void testInterpretExtendNonPublicClass()
205+
throws BadLocationException, IOException, InterruptedException, InterpreterException {
206+
_log.log("testInterpretExtendNonPublic started");
207+
208+
OpenDefinitionsDocument doc = setupDocument(UNARY_FUN_NON_PUBLIC_CLASS_TEXT);
209+
final File file = tempFile();
210+
saveFile(doc, new FileSelector(file));
211+
CompileShouldSucceedListener listener = new CompileShouldSucceedListener();
212+
_model.addListener(listener);
213+
listener.compile(doc);
214+
if (_model.getCompilerModel().getNumErrors() > 0) {
215+
fail("compile failed: " + getCompilerErrorString());
216+
}
217+
listener.checkCompileOccurred();
218+
_model.removeListener(listener);
219+
assertCompileErrorsPresent(_name(), false);
220+
221+
// Make sure .class exists
222+
File compiled = classForJava(file, "UnaryFun");
223+
assertTrue(_name() + "Class file should exist after compile", compiled.exists());
224+
225+
_classPathManager.addBuildDirectoryCP(compiled.getParentFile());
226+
227+
try {
228+
_interpreter.interpret("UnaryFun f = new UnaryFun() { public Object apply(Object arg) { return (Integer)arg * (Integer)arg; }}");
229+
fail("Should fail with 'cannot access its superclass' exception.");
230+
}
231+
catch(edu.rice.cs.dynamicjava.interpreter.CheckerException ce) {
232+
assertTrue(ce.getMessage().indexOf("cannot access its superclass")>=0);
233+
}
234+
}
235+
236+
/** Tests that we don't get an error for public classes. */
237+
@SuppressWarnings("unchecked")
238+
public void testInterpretExtendPublicClass()
239+
throws BadLocationException, IOException, InterruptedException, InterpreterException {
240+
_log.log("testInterpretExtendPublic started");
241+
242+
OpenDefinitionsDocument doc = setupDocument(UNARY_FUN_PUBLIC_CLASS_TEXT);
243+
final File file = createFile("UnaryFun.java");
244+
saveFile(doc, new FileSelector(file));
245+
CompileShouldSucceedListener listener = new CompileShouldSucceedListener();
246+
_model.addListener(listener);
247+
listener.compile(doc);
248+
if (_model.getCompilerModel().getNumErrors() > 0) {
249+
fail("compile failed: " + getCompilerErrorString());
250+
}
251+
listener.checkCompileOccurred();
252+
_model.removeListener(listener);
253+
assertCompileErrorsPresent(_name(), false);
254+
255+
// Make sure .class exists
256+
File compiled = classForJava(file, "UnaryFun");
257+
assertTrue(_name() + "Class file should exist after compile", compiled.exists());
258+
259+
_classPathManager.addBuildDirectoryCP(compiled.getParentFile());
260+
261+
_interpreter.interpret("UnaryFun f = new UnaryFun() { public Object apply(Object arg) { return (Integer)arg * (Integer)arg; }}");
262+
}
263+
}

drjava/src/edu/rice/cs/drjava/model/repl/InteractionsModelTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,8 @@ public void run() {
648648
_log.log("testInteractionsHistoryStoredCorrectly ended");
649649
}
650650

651-
/** A generic InteractionsModel for testing purposes. (Used here and in InteractionsPaneTest.) */
651+
/** A generic InteractionsModel for testing purposes. (Used here, in InteractionsPaneTest,
652+
* and in InteractionsModelErrorTest.) */
652653
public static class TestInteractionsModel extends InteractionsModel {
653654
String toEval = null;
654655
String addedClass = null;
@@ -745,7 +746,7 @@ protected void _interpret(String toEval) {
745746
/** This test model includes a slave JVM, just like a DefaultGlobalModel. It must be disposed before it is
746747
* deallocated to kill the slave JVM. TODO: the mutation in this class is disgusting -- Corky 2 June 06.
747748
*/
748-
private static class IncompleteInputInteractionsModel extends RMIInteractionsModel {
749+
public static class IncompleteInputInteractionsModel extends RMIInteractionsModel {
749750
boolean continuationException; // This appears to be the negation of syntaxException making it redundant!
750751
boolean syntaxException;
751752

0 commit comments

Comments
 (0)