Method scope inside Java switch statement - java

In a rather loose way this question follows on from my previous one. The context here is building Android APKs with Phonegap CLI configured, via build-extras.gradle to use Java 7. Here is my code
public boolean execute(String action, JSONArray data,
CallbackContext cbc) throws JSONException
{
Context ctxt = cordova.getActivity().getApplicationContext();
// return doSave(data,cbc,ctxt);
//the above compiles correctly
//doSave is a private method in the same class
switch(action)
{
case "save":return doSave(data,cbc,ctxt);break;
//the compiler complains about an `unreachable statement`
//other case statements ommitted for clarity
default:cbc.error("Unknown action: " + action);return false;
}
return false;
//without this return the compiler is upset.
}
I am having some difficulty understanding two issues here
As far as I can tell even without that last return I have defined a clear path of execution thanks to the switch...default clause so I cannot see why it requires a return statement there
So inside the switch statement the private doSave method in the same class somehow becomes invisible?
I am coming back to Java after a long gap where I did only JS and PHP. However, I have done a great deal of Delphi coding at one time so I appreciate the rigor imposed by the Java compiler. In this instance though it seems to me that it is a bit excessive. Or perhaps I am misunderstanding something?

return doSave(data,cbc,ctxt);break;
Your break statement is unreachable.
You should remove that statement, as well as the final return false; statement, which is also unreachable.

Related

JavaCC creating custom Token class

I'm working on a school assignment for my compiler and interpreters course and our current task is to create a scanner and a set of tokens using JavaCC. I have a pretty solid understanding of how JavaCC works but my problem is finding resources online to help me out when I get stuck. I am working on creating a custom Token class, let's call it NewToken.Java. I know that the base Token class has an image variable and a kind variable but I want to implement my own variable "value". Furthermore I want to figure out how I can assign this value. I want the value variable to hold the literal value of what I scan, for example, my NewToken is being matched to the following
< IDENTIFIER:(< LETTER >)+ ( < LETTER > | < DIGIT >)* >
< #LETTER:["a" - "z"] >
< #DIGIT: ["0" - "9"] >
so something along the lines of Name123Name would get caught and when it does I want to store the string "Name123Name" into the 'value' variable of my NewToken object. I hope this makes sense, I am still new to JavaCC and may be calling things by there wrong name here.
public NewToken(){}
public NewToken(int kind){
this(kind,null);
}
public NewToken(int kind, String image){
this.kind=kind;
this.image=image;
this.value=image;
}
public String toString(){
return image;
}
public static Token newToken(int ofKind, String image){
switch(ofKind){
default : return new Token(ofKind, image);
}
}
public static Token newToken(int ofKind){
return newToken(ofKind, null);
}
}
Above is part of my code for the NewToken class, I have it extending Token and implementing java.io.serializable. I created by using the code generated for Token.java. I also have my variable declarations and my getValue() function which are not listed here to save space. I'm not looking for anyone to do my work for me I just need some guidance on how I would get this working, thank you in advance.
First off, I think the newToken routine should return objects of type NewToken rather than Token.
public static Token newToken(int ofKind, String image){
return new NewToken(ofKind, image);
}
public static Token newToken(int ofKind){
return new NewToken(ofKind, null);
}
(I don’t think you need that second method. But, I’m not completely sure, so I’ll leave it.)
It’s a bit unclear to me how you want value to differ from image, but I’m going to assume that you can compute the desired value for value from the image and the kind. And I’ll further assume that you have implemented this function as a static method.
private static String computeValue(int kind, String image) {...}
Delete the first two constructors and the remaining one should be:
private NewToken(int kind, String image){
this.kind = kind;
this.image = image;
this.value = computeValue( kind, image );
}
The answer that Professor Norvell is giving you is based on using a very old, obsolete version of JavaCC. The way he's suggesting you go about things is probably about the best way of doing it, if you were going to use the legacy JavaCC.
However, the most advanced version of JavaCC is JavaCC 21 and it handles this sort of use case straight out of the box in a very clean, elegant manner. See here for information on this specifically.
As you can see, you can put annotations in your grammar file that cause the various Token subclasses to be generated and used.
Also, JavaCC 21 has code injection that allows you to inject code directly into the any generated files, including the Token subclasses. That feature is not at all present in legacy JavaCC either. But using that, you could just inject your computeValue method right into the appropriate Token subclass.
INJECT NewToken :
{
private static String computeValue(int kind, String image) {...}
}
You put that in your grammar and the computeValue method just gets inserted into the generated NewToken.java file.
By the way, there is an article about JavaCC 21 that appeared recently on dzone.com.

drjava: Is closing upon cancelling intended?

Whenever I try to close a file in drjava after making some edits and not saving, the program, as expected, gives the dialog box:
"[Filename] has been modified. Would you like to save it?"
In many cases, I'll decide at this point to cancel the closing and make some more edits, then save the file manually.
Unfortunately, hitting "Cancel" has the same effect as hitting "No": the window closes without saving, and I lose my work.
Is this the intended behavior of drjava? Or is there some option to select / some code I can use to fix the problem? Although as long as I remember the behavior it's manageable, it's still pretty inconvenient.
It's open source, so we can take a look at the implementation. Here's the code that opens the dialog (some code omitted) from the newest branch:
private boolean _fileSaveHelper(OpenDefinitionsDocument doc, int paneOption) {
...
int rc = JOptionPane.showConfirmDialog(MainFrame.this, text, "Save " + fname + "?", paneOption);
switch (rc) {
case JOptionPane.YES_OPTION:
boolean saved = false;
if (notFound) saved = _saveAs();
else saved = _save();
if (doc != lastActive) {
_model.setActiveDocument(lastActive); // breaks when "if" clause omitted
}
return saved;
case JOptionPane.NO_OPTION:
if (doc != lastActive) {
_model.setActiveDocument(lastActive); // breaks when "if" clause omitted
}
return true;
case JOptionPane.CLOSED_OPTION:
case JOptionPane.CANCEL_OPTION:
return false;
default: // never executed
throw new RuntimeException("Invalid option: " + rc);
}
}
There are separate cases for "no" and "cancel", so it looks like they do try to handle it properly. Thus it's probably a bug. The method is referenced by this method
public boolean quitFile(OpenDefinitionsDocument doc) {
return _fileSaveHelper(doc, JOptionPane.YES_NO_CANCEL_OPTION);
}
which is referenced somewhere outside MainFrame.java. I am not inclined to look into it as I don't even have a Java IDE installed. If you wish, you can fork the project and use an IDE like Eclipse to quickly find the references to the method. Speaking of which, I'd suggest just using Eclipse as I remember Dr. Java offering little in the way of basic features such as code completion and formatting.

Java Jinput: rescan / reload controllers

I am using java jinput library to read data from joypad, and I have trouble reloading Controllers, I use this to load them:
public Controller[] findStickControllers() {
ControllerEnvironment ce =
ControllerEnvironment.getDefaultEnvironment();
Controller[] cs = ce.getControllers();
System.out.println(cs.length); //test
ArrayList<Controller> sel = new ArrayList<>();
for (Controller c: cs) {
if(c.getType() == Type.STICK) {
sel.add(c);
}
}
return sel.toArray(new Controller[]{});
}
This works fine, but if I disconnect my controller, calling this will find it again, and vice versa (connecting it after the first check will not find it at all).
I have tried to put sleep before the fist lookup, with these results:
Controllers are acctually scanned when this method is called first time (not at start of the program)
When called again, this always returns same controllers as it returned for the first time.
First call will also write warning bellow
Even when controller is connected (and works), then disconnected (it will still find it though) and reconnected, it will not work
Warning from point 3: (didn't format well in the list)
WARNING: Found unknown Windows version: Windows 8
Attempting to use default windows plug-in.
Loading: net.java.games.input.DirectAndRawInputEnvironmentPlugin
I am using Win 8, and had same problem on Win 7. I had also tried this with mouse, same results.
How can I acctually reload controllers for the 2nd, 3rd, and so on time?
I encountered the same problem. The reason is that the actual hardware scan happens only once for each DefaultControllerEnvironment object. Since the only accessible instantiation is a singleton, it never does another scan.
A simple way to force a hardware scan is to create a new object, but neither the class nor the constructor are public. You can however work around this limitation by calling the constructor via reflection.
Rescan
private static ControllerEnvironment createDefaultEnvironment() throws ReflectiveOperationException {
// Find constructor (class is package private, so we can't access it directly)
Constructor<ControllerEnvironment> constructor = (Constructor<ControllerEnvironment>)
Class.forName("net.java.games.input.DefaultControllerEnvironment").getDeclaredConstructors()[0];
// Constructor is package private, so we have to deactivate access control checks
constructor.setAccessible(true);
// Create object with default constructor
return constructor.newInstance();
}
Usage
// Be aware that creating a new environment is fairly expensive
Controller[] controllers = createDefaultEnvironment().getControllers();
Remove Windows 8 Warnings
/**
* Fix windows 8 warnings by defining a working plugin
*/
static {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
String os = System.getProperty("os.name", "").trim();
if (os.startsWith("Windows 8")) { // 8, 8.1 etc.
// disable default plugin lookup
System.setProperty("jinput.useDefaultPlugin", "false");
// set to same as windows 7 (tested for windows 8 and 8.1)
System.setProperty("net.java.games.input.plugins", "net.java.games.input.DirectAndRawInputEnvironmentPlugin");
}
return null;
}
});
}
If you use the accepted answer, you might want to consider killing the thread that was spawned by the previous environment before setting a new one because it won't be cleaned up otherwise. You can do so by calling something like:
final Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (final Thread thread : threadSet) {
final String name = thread.getClass().getName();
if (name.equals("net.java.games.input.RawInputEventQueue$QueueThread")) {
thread.interrupt();
try {
thread.join();
} catch (final InterruptedException e) {
thread.interrupt();
}
}
}
The warning is because the last time I updated that code windows 7 wasn't even out IIRC, I'll update it.
The controller reload is a feature that has been requested a number of times, but no-one deems it important enough to spend any time implementing it. If you submit a patch I'll take a look and see about committing it. Until someone finds it important enough to spend the time to write it, it's just a missing feature.
I had the same problem before.
I add the rescanning feature (for Windows back-end only) and post the patch on Java gaming forum but no ones seem interested in to integrate it.
So if you need it, apply my patch from here: http://www.java-gaming.org/topics/rescan-controllers/24782/msg/224604/view.html#msg224604

Java entering an if statement that is false

I'm running into the strangest error in this program, which is confirmed when debugging it. I have the following code (boiled down to highlight the problem, of course):
BHFrame.java
public class BHFrame
{
private boolean uSS;
private StateSaver stateSaver;
public BHFrame(boolean useInternalStateSaver)
{
//Init code
uSS = useInternalStateSaver;
//More init code
System.out.println(uSS);
if (uSS)
{System.out.println("Entered 1");
stateSaver = new StateSaver(title, false);
stateSaver.addSaveable(getThis());
}
//More init code
System.out.println(uSS);
if (uSS)
{System.out.println("Entered 2");
try
{
stateSaver.loadState();
stateSaver.putState(getThis());
}
catch (IOException ex)
{
alertUserOfException(ex);
}
}
}
}
GUI.java
public class GUI extends BHFrame
{
public GUI(boolean useInternalStateSaver)
{
super(useInternalStateSaver);
}
}
Main.java
public class Main
{
public static void main(String[] args)
{
GUI gui = new GUI(false);
}
}
Output
false
false
Entered 2
Exception in thread "main" java.lang.NullPointerException
at bht.tools.comps.BHFrame.<init>(BHFrame.java:26)
at bhms.GUI.<init>(GUI.java:5)
at bhms.Main.main(Main.java:5)
The class BHFrame is extended and run from a child class that calls this constructor, but that really shouldn't affect this behavior. The problem is that, when false is passed to the constructor as useInternalStateSaver, the first if (uSS) is skipped, but the second is entered. Upon debugging, I found that uSS is false throughout runtime, including on the line of the second if statement, here. Why would Java enter an if statement when the condition returns false? Before you ask, I did delete the .class files and recompile it just in case there was some residual code messing with it, but I got the same result. And rest assured, all the references to the uSS variable are displayed here.
Solution
As it turns out, this appears to be a bug in NetBeans 7.1 Build 201109252201, wherein the IDE doesn't properly insert new code into the compiled .class files. The problem was fixed by compiling the files externally. A bug report has been submitted.
Whatever's throwing that exception is probably not in your posted code.
It's not being caught by your catch statement, which only catches IOException.
It's a NullPointerException and can occur anywhere.
You have shown no indication that the code inside your if block is actually executing. In your screenshot, there is absolutely know way of knowing if your if block is entered or not. There are no logging statements.
Add debugging messages at various points to see exactly what is happening. Or, you know, look at line 26 (wayyyyy before your posted code) to see why you're getting a NullPointerException.
I've seen crazy stuff like this when there is bad RAM on the machine. You might want to run memtest86.
You might also consider deleting all of your project class files, and then doing a build. Maybe you changed Main.java, but it was never recompiled. I hate that when that happens.
This is just a guess, because I can't see the code you are mentioning, but I reckon you have defined a local variable uSS in the second //More init code segment.
Once you define a local variable named the same as an instance variable, it 'hides' the instance variable. Better to qualify all instance variables with this.
So, try qualifying all above accesses of uSS with this. ... (this.uSS)
Even if this isn't the issue, it might be better to post the full code anyway.
HTH

How to detect that code is running inside eclipse IDE

How to detect that code is running inside eclipse IDE
I am not aware of a generic way to get this kind of information.
One suggestion:
When you start a Java program (or a web server) inside Tomcat, simply add an argument that will indicate that this program is launched by Eclipse.
You can do that by opening the "Open Run Dialog" ("Run" menu), then select your type of application and add in the "Arguments" tab a -DrunInEclipse=true.
In your Java code, you can check the value of the property:
String inEclipseStr = System.getProperty("runInEclipse");
boolean inEclipse = "true".equalsIgnoreCase(inEclipseStr);
This way, if the program is not running inside Eclipse (or unfortunately if you forgot to set the property) the property will be null and then the boolean inEclipse will be equal to false.
Although I agree that having the code detecting a single IDE as the dev env is not an optimal solution, the following code works.
Like others proposed, using a flag at runtime is better.
public static boolean isEclipse() {
boolean isEclipse = System.getProperty("java.class.path").toLowerCase().contains("eclipse");
return isEclipse;
}
1) Create a helper method like:
public boolean isDevelopmentEnvironment() {
boolean isEclipse = true;
if (System.getenv("eclipse42") == null) {
isEclipse = false;
}
return isEclipse;
}
2) Add an environment variable to your launch configuration:
3) Usage example:
if (isDevelopmentEnvironment()) {
// Do bla_yada_bla because the IDE launched this app
}
Actually the code is not being run inside Eclipse, but in a separate Java process started by Eclipse, and there is per default nothing being done by Eclipse to make it any different than any other invocation of your program.
Is the thing you want to know, if your program is being run under a debugger? If so, you cannot say for certain. You CAN, however, inspect the arguments used to invoke your program and see if there is anything in there you do not like.
If your workspace matches some pattern like "/home/user/workspace/Project" you can use the code below:
Boolean desenv = null;
boolean isDevelopment() {
if (desenv != null) return desenv;
try {
desenv = new File(".").getCanonicalPath().contains("workspace");
}
catch (IOException e) {
e.printStackTrace();
}
return desenv;
}
A more generic and precise way, that can be used on any IDE would be loop at:
ManagementFactory.getRuntimeMXBean().getInputArguments()
looking for "-Xdebug" || (starting with) "-agentlib:jdwp=".
I came with this from #saugata comment here.
This is excellent if you want to throw a conditional exception preventing the application from simply exiting. Use a boolean like "ideWait" and add it to Eclipse watch expressions as ideWait=false, so whenever you stop at that throw, and "drop to frame" you can continue debugging happily (I mean it!)
I don't think there is any way to do this. But what I would suggest is just a command line argument such as 'debug'. Then in your main method just do
if (args.length > 0 && args[0].equalsIgnoreCase("debug")) {
// do whatever extra work you require here or set a flag for the rest of the code
}
This way you can also get your extra code to run whenever you want just by specifiying the debug parameter but under normal conditions it will never execute.
This might work if your alternative execution work flow provides a different set of dependencies:
boolean isRunningInEclipe = false;
try {
Workbench.getInstance();
isRunningInEclipe = true;
} catch (NoClassDefFoundError error) {
//not running in Eclipse that would provide the Workbench class
}
You could detect if you're inside a JAR or not, as per Can you tell on runtime if you're running java from within a jar?
Eclipse will run your app from the classes/ dir, whereas most of your end users will be running the app from a JAR.
System.out.println("Is my parent eclipse[.exe]? " +
ProcessHandle.current()
.parent()
.flatMap(parent -> parent.info().command())
.orElse("")
.matches("^.*eclipse(\\.exe)?$"));
You may try something like this:
if (ClassLoader.getSystemResource("org/eclipse/jdt/core/BindingKey.class")!=null){
System.out.println("Running within Eclipse!!!");
} else {
System.out.println("Running outside Eclipse!!!");
}

Categories