I am trying to build my own parser based on the existing Java grammar.
Even if I use the Java7 grammar from the source repo, generate the parser and use the TestRig from antlr-4.9.3-complete.jar given the code:
1 public class Test {
2 public static void main() {
3 test
4 int b = 1;
5 }
6 }
I get the following error:
line 4:8 no viable alternative at input 'test\n int'
So for some reason it concatenates the incorrect "test" line with correct "int" line.
Also it says "line 4:8" pointing at the "int" line when it should be pointing to "test" (line 3).
(In a regular Java editor I would see a correct error highlighting for the "test" word which would sound like):
"Syntax error, insert "VariableDeclarators" to complete LocalVariableDeclaration"
What do I do to arrive at a similar error with ANTLR so it only picks on the wrong "test" line?
Most likely it's just my misunderstanding how antlr interprets the errors, then how would I get the listener to at least report correctly the starting line?
You can't compare a sophisticated editor/IDE with a parser (generated by ANTLR). A text editor/IDE knows more about the input source and can look up if test is a valid type, and give a meaningful error message if the type cannot be found.
ANTLR's parser rule "sees" test int b as an Identifier, an INT and another Identifier token and cannot match any parser rule for these tokens, resulting in the error starting at the identifier test.
For example, if class test {} was in the classpath, then input without int would be valid:
public class Test {
public static void main() {
test
/*int*/ a = 1;
}
}
It wouldn't compile of course, but the syntax would be correct:
Code:
Mockito.when(mongoRepo.findByIdAndIsDeleted(objId, false)).thenReturn(responseObj);
// here mongoRepo is MongoRepository and objId is UUID
When I run the test case I'm getting the following exception:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 2 matchers expected, 1 recorded:
I also tried some other ways but no luck
Second example I tried:
Mockito.when(mongoRepo.findByIdAndIsDeleted(any(), anyBoolean())).thenReturn(responseObj);
// here mongoRepo is MongoRepository
The third example I tried:
Mockito.when(mongoRepo.findByIdAndIsDeleted(any(UUID.class), Mockito.eq(false))).thenReturn(responseObj);
// here mongoRepo is MongoRepository
I'm getting the same exception.
Any help would be appreciated!!
I'm using MockitoJUnitRunner
If I remember correctly, Mokito provided an additional explanation for this error and printed the explanation in the run log.
Or you could check if the Matcher method is referenced correctly, some methods with the same name return Matcher for different purposes?
I'm having a very frustrating issue at the moment and perhaps the answer lies here?
I'm currently having an issue with if statements.
I want my core.java class to contain an if statement which closes the entire program if my variable counter reaches 2.
private int counter = 0;
//located in the class Ending
I implemented that using a seperate method addCounter()
which goes as
public void addCounter(){
this.counter ++;
}
//this will be called in core.java
I also have a getter which is supposed to return the value of counter
public int getCounter(){
return counter;
}
//this will be called in core.java
Decleration of changeState in core.java
Ending changeState = new Ending();
//(As per request)
The real issue is described here:
I can't seem to come up with a fitting if statement which checks if the method getCounter has reached '2' after addCounter();has been invoked several times
My first idea was to use something such as
if(changeState.getCounter().equals(2)){
System.exit(0);
}
//I also tried using:
if(changeState.getCounter() == 2)
//however, that didn't work either
both lines give me numerous errors which I can't wrap my head around:
.java:476: error: illegal start of type: if(changeState.getCounter().equals(2)){
.java:476: error: <identifier> expected: if(changeState.getCounter().equals(2)){
.java:476: error: ';' expected: if(changeState.getCounter().equals(2)){
.java:476: error: illegal start of type: if(changeState.getCounter().equals(2)){
.java:476: error: illegal start of type: if(changeState.getCounter().equals(2)){
.java:476: error: ';' expected: if(changeState.getCounter().equals(2)){
Could anyone elaborate on what is going wrong and what should be done to overcome this issue?
Thank you in advance!
C.C.
.equals(2) is incorrect , the 2 in the equals method is a primitive type int literal not an Object or String type.
.equals() method uses either a type "String"
counter.equals("2")
or it uses a type "object" to compare
.equals(((Object)new String("2")))
If you must use .equals() method then it would be
if(counter.getCounter().equals(new Integer(2).toString())){
System.exit(0);
}
Although that really should be simpler such as
if(counter.getCounter() == 2){
System.exit(0);
}
My answer lied here all along.
If anyone else is having similar kind of issue, it seems that you simply can't invoke an object inside a class unless it's in a method.
I admit that this does solve my issue entirely, but it did show me a valuable lesson.
Good luck!
I am running a method that returns a boolean. The method does not change any data. The first line returns false but then when I run the assertion test it says that it is returning null. Any thoughts?
System.out.println(fb.existsInNetwork(x)); // returns false
assertFalse(fb.existsInNetwork(x)); // junit.framework.AssertionFailedError: null
we know that if a method returns a boolean, it cannot return null. I suspect that instead you should interpret this as "Assertion failed, and the message is: null". Try instead calling the version of assertFalse which takes a message:
assertFalse("didn't expect x to be in network", fb.existsInNetwork(x))
Edit: I initially accepted thejh's answer, but I wasn't really satisfied with it since I wanted to make proper use of generics. So, I kept doing research and found a solution. Read about it in my answer below.
Here's a little self-contained piece of Java code which shows what I'm trying to do. It compiles, runs, and behaves correctly.
1 import java.lang.reflect.Method;
2 import java.lang.reflect.InvocationTargetException;
3
4 public class Example
5 {
6 public static <T> void foo(Method method, String target, Object argument, T expectedReturn) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
7 {
8 T actualReturn = (T) method.invoke(target, argument);
9 System.out.print(actualReturn.equals(expectedReturn));
10 }
11
12 public static void main(String[ ] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
13 {
14 foo(String.class.getMethod("charAt", int.class), "test", 1, 'e');
15 }
16 }
Running this prints true to the console, which is what I expected. What's bothering me is that, due to the cast on line 8, I'm getting a warning when I compile it, as follows (jGRASP is my IDE, by the way).
----jGRASP exec: javac -g -Xlint:unchecked Sandbox.java
Sandbox.java:8: warning: [unchecked] unchecked cast
found : java.lang.Object
required: T
1 warning
----jGRASP: operation complete.
Originally, I tried line 8 without the cast, but that failed to compile with an error complaining about finding an Object when it required T (invoke returns an Object). Later on, I rewrote it like this, blindly hoping to get rid of the warning.
T actualReturn = method.getReturnType( ).cast(method.invoke(target, argument));
But that gives a compile error that I can't make head nor tail of.
----jGRASP exec: javac -g -Xlint:unchecked Sandbox.java
Sandbox.java:8: incompatible types
found : capture#898 of ?
required: T
1 error
----jGRASP wedge: exit code for process is 1.
----jGRASP: operation complete.
And that number next to capture# is different each time I try to compile with that same line of code.
So, what exactly is the problem? Why am I getting the warning when I cast the object returned by invoke to the type variable? Does that indicate that I'm doing something wrong? How can I write this so that the warning goes away? And I'd prefer not to suppress it with an annotation, as that doesn't seem like much of a solution to me.
I looked into this some more and found that I could solve the problem by using class literals as runtime type tokens, as discussed in the Java Tutorials.
I had the right idea with method.getReturnType( ).cast(...), but it didn't work because the return type of getReturnType( ) is Class<?>, and I needed Class<T>.
So, here's what the method looks like now.
public static <T> void foo(Class<T> returnType, Method method, String target, Object argument, T expectedReturn) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
{
T actualReturn = returnType.cast(method.invoke(target, argument));
System.out.print(actualReturn.equals(expectedReturn));
}
And here's a sample call.
foo(Character.class, String.class.getMethod("charAt", int.class), "test", 1, 'e');
That compiles without warnings and prints true to the console. Note that if you're expecting the underlying method to return a primitive, the returnType parameter needs to be its respective wrapper class.
Why do you cast it to T? Why don't you do it this way?
Object actualReturn = method.invoke(target, argument);
System.out.print(actualReturn.equals(expectedReturn));
Oh, and in case the method could return null and expectedReturn isn't, this is better:
Object actualReturn = method.invoke(target, argument);
System.out.print(expectedReturn.equals(actualReturn));
So, what exactly is the problem? Why
am I getting the warning when I cast
the object returned by invoke to the
type variable?
Method can return any Object. And it can't be cast to T in all cases.
Does that indicate that I'm doing
something wrong?
it's bad practice to mix reflection and generics, imho.
How can I write this so that the
warning goes away?
Personally, I think you can't avoid this warning without refactoring.