I'm reading the chapter 12 on the Combined Pattern in Head First Design Patterns.
On page 541,the sample DJView,it cant't run correctly in my computer.when i press the 'start', the program only sounds once rather than circularly .
i'm not sure whether because of the environment of my system.
but if i add one line code in the method meta of the class BeatModel,it works.like:
public void meta(MetaMessage message) {
if (message.getType() == 47) {
beatEvent();
sequencer.setMicrosecondPosition(0); //add this line
sequencer.start();
setBPM(getBPM());
}
}
can anyone tell me why? i'm so confused,is something wrong with the code given by the book or some other reason? help me .
Thanks in advance!!
So sorry,the code is long so i could not put all here,you could download from the offical website,here is the link http://www.headfirstlabs.com/books/hfdp/HeadFirstDesignPatterns_code102507.zip
you can find the sample in this folder '\HeadFirstDesignPatterns_code102507\HF_DP\src\headfirst\combined\djview'.
run the class DJTestDrive.java
Look forward to your help.
EDIT #2: For completeness' sake, the author of Head First Design Patterns Elisabeth Freeman herself has made a note of the fact that the code in her book has only been tested with Java 1.4. She has promised to take our feedback into account.
EDIT: There seems to be a bug with the Sequencer.setTempoInBPM during play. Your approach with setting the microsecond position to 0 is the right approach -- it basically rewinds the sequencer as soon as it ends (i.e. message type = 47).
Unfortunately, the sample code seems incorrect. There are several problems:
The sequencer is not initialized to play in a loop
The meta() method resets the BPM and renotifies all listeners, but does not reset the sequencer to its original position, which you did to get it to work. However, this method does not need to do anything so long as the sequencer is set to play in a loop.
The off() method sets the BPM to 0, which will fast forwards the sequencer to the end of all loops -- which means next time you start the player, it will start from the end and will play nothing.
These change should do the trick:
#1 In method BeatModel.buildTrackAndStart, add sequencer.setLoopCount as follows:
public void buildTrackAndStart() {
// ...
try {
sequencer.setSequence(sequence);
sequencer.setLoopCount(Integer.MAX_VALUE); // play forever
} catch(Exception e) {
// ...
}
#2 Remove all statements from method BeatModel.meta(MetaMessage):
public void meta(MetaMessage message) {
}
#3 Remove setBPM(0) from method BeatModel.off():
public void off() {
// -- remove this -- setBPM(0);
sequencer.stop();
}
On Java 8 just adding the
sequencer.setMicrosecondPosition(0);
to the BeatModel.meta() makes it work just fine!
Greetings to all,
hebgeenbrug
I meet the similar error when reading. in my computer the processBar doesn`t update.
1.First I add "sequencer.setMicrosecondPosition(0);" in "public void meta(MetaMessage message)" ;
2.Second I delete "sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);" in "public void setUpMidi()"; it continuous sound but "meta(MetaMessage message)" will not be notice,so ProcessBar not update.
3.Then it works
may be my experience can help others.
Related
Considering the following code
public static void main(String...arg){
//do something
if(<<the method has called by a new process>>){System.exit(0);}
else{System.setProperty("main_result","0");return;}
}
the main method would be called by a separated process by JVM or existing process, now how can I find it out?
Thanks in advance
Let's clarify: there might be another class with a main that was started, or the main is somehow called again.
Normally you want to call System.exit(0) (or return;?) but when called from the program itself you want to end in System.setProperty("main_result","0");.
public static void otherMain(String[] args) {
Main.main(args);
}
public static void main(String[] args) {
...
StackTraceElement[] elems = Thread.currentThread().getStackTrace();
//for (StackTraceElement elem : elems) {
// System.out.printf("%s%n", elem.getClassName());
//}
if (elems.length > 2) { // [0] Thread [1] main
System.setProperty("main_result","0");
}
}
In java, every Java process runs in its own JVM. So, the "same" main
method cannot be called by a different process under normal
circumstances
Even if you run the same program twice, they will be running in their
own JVMs.
You can try one thing.. Keep a static variable in your program, run it and
make it sleep for a long period of time (process 1).. Now, run the same
program again and update the static variable(runs in process 2).. See, whether it will be
updated in the first process (No, it won't be updated as each process will have it's own
set of variables..)
Do you really need it? Just don't use System.exit(0); and refactor main method to finish gracefully.
Calling System.setProperty in both cases - when run as new process and also as a class on classpath, will not make any difference.
Edit: Finding out who is calling the method is not easy and definitely bad practice.
I would refactor the code as follows:
public static void main(String...arg){
System.exit(doStuff(arg));
}
public static int doStuff(String... arg) {
//do something
}
To access this logic within the same JVM you can now call MyClass.doStuff and get the return value directly.
It would be better to consider refactoring and get rid of such problem.
Otherwise the following code can help:
if(Thread.currentThread().getStackTrace()[1].getClassName().equals(
System.getProperty("sun.java.command"))){
System.out.println("!");
}
Will not work if there is no "sun.java.command" property (on not Sun/Oracle JVMs it may absent)
I'm using LuaJ to run user-created Lua scripts in Java. However, running a Lua script that never returns causes the Java thread to freeze. This also renders the thread uninterruptible. I run the Lua script with:
JsePlatform.standardGlobals().loadFile("badscript.lua").call();
badscript.lua contains while true do end.
I'd like to be able to automatically terminate scripts which are stuck in unyielding loops and also allow users to manually terminate their Lua scripts while they are running. I've read about debug.sethook and pcall, though I'm not sure how I'd properly use them for my purposes. I've also heard that sandboxing is a better alternative, though that's a bit out of my reach.
This question might also be extended to Java threads alone. I've not found any definitive information on interrupting Java threads stuck in a while (true);.
The online Lua demo was very promising, but it seems the detection and termination of "bad" scripts is done in the CGI script and not Lua. Would I be able to use Java to call a CGI script which in turn calls the Lua script? I'm not sure that would allow users to manually terminate their scripts, though. I lost the link for the Lua demo source code but I have it on hand. This is the magic line:
tee -a $LOG | (ulimit -t 1 ; $LUA demo.lua 2>&1 | head -c 8k)
Can someone point me in the right direction?
Some sources:
Embedded Lua - timing out rogue scripts (e.g. infinite loop) - an example anyone?
Prevent Lua infinite loop
Embedded Lua - timing out rogue scripts (e.g. infinite loop) - an example anyone?
How to interrupt the Thread when it is inside some loop doing long task?
Killing thread after some specified time limit in Java
I struggled with the same issue and after some digging through the debug library's implementation, I created a solution similar to the one proposed by David Lewis, but did so by providing my own DebugLibrary:
package org.luaj.vm2.lib;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
public class CustomDebugLib extends DebugLib {
public boolean interrupted = false;
#Override
public void onInstruction(int pc, Varargs v, int top) {
if (interrupted) {
throw new ScriptInterruptException();
}
super.onInstruction(pc, v, top);
}
public static class ScriptInterruptException extends RuntimeException {}
}
Just execute your script from inside a new thread and set interrupted to true to stop the execution. The exception will be encapsulated as the cause of a LuaError when thrown.
There are problems, but this goes a long way towards answering your question.
The following proof-of-concept demonstrates a basic level of sandboxing and throttling of arbitrary user code. It runs ~250 instructions of poorly crafted 'user input' and then discards the coroutine. You could use a mechanism like the one in this answer to query Java and conditionally yield inside a hook function, instead of yielding every time.
SandboxTest.java:
public static void main(String[] args) {
Globals globals = JsePlatform.debugGlobals();
LuaValue chunk = globals.loadfile("res/test.lua");
chunk.call();
}
res/test.lua:
function sandbox(fn)
-- read script and set the environment
f = loadfile(fn, "t")
debug.setupvalue(f, 1, {print = print})
-- create a coroutine and have it yield every 50 instructions
local co = coroutine.create(f)
debug.sethook(co, coroutine.yield, "", 50)
-- demonstrate stepped execution, 5 'ticks'
for i = 1, 5 do
print("tick")
coroutine.resume(co)
end
end
sandbox("res/badfile.lua")
res/badfile.lua:
while 1 do
print("", "badfile")
end
Unfortunately, while the control flow works as intended, something in the way the 'abandoned' coroutine should get garbage collected is not working correctly. The corresponding LuaThread in Java hangs around forever in a wait loop, keeping the process alive. Details here:
How can I abandon a LuaJ coroutine LuaThread?
I've never used Luaj before, but could you not put your one line
JsePlatform.standardGlobals().loadFile("badscript.lua").call();
Into a new thread of its own, which you can then terminate from the main thread?
This would require you to make some sort of a supervisor thread (class) and pass any started scripts to it to supervise and eventually terminate if they don't terminate on their own.
EDIT: I've not found any way to safely terminate LuaJ's threads without modifying LuaJ itself. The following was what I came up with, though it doesn't work with LuaJ. However, it can be easily modified to do its job in pure Lua. I may be switching to a Python binding for Java since LuaJ threading is so problematic.
--- I came up with the following, but it doesn't work with LuaJ ---
Here is a possible solution. I register a hook with debug.sethook that gets triggered on "count" events (these events occur even in a while true do end). I also pass a custom "ScriptState" Java object I created which contains a boolean flag indicating whether the script should terminate or not. The Java object is queried in the Lua hook which will throw an error to close the script if the flag is set (edit: throwing an error doesn't actually terminate the script). The terminate flag may also be set from inside the Lua script.
If you wish to automatically terminate unyielding infinite loops, it's straightforward enough to implement a timer system which records the last time a call was made to the ScriptState, then automatically terminate the script if sufficient time passes without an API call (edit: this only works if the thread can be interrupted). If you want to kill infinite loops but not interrupt certain blocking operations, you can adjust the ScriptState object to include other state information that allows you to temporarily pause auto-termination, etc.
Here is my interpreter.lua which can be used to call another script and interrupt it if/when necessary. It makes calls to Java methods so it will not run without LuaJ (or some other Lua-Java library) unless it's modified (edit: again, it can be easily modified to work in pure Lua).
function hook_line(e)
if jthread:getDone() then
-- I saw someone else use error(), but an infinite loop still seems to evade it.
-- os.exit() seems to take care of it well.
os.exit()
end
end
function inithook()
-- the hook will run every 100 million instructions.
-- the time it takes for 100 million instructions to occur
-- is based on computer speed and the calling environment
debug.sethook(hook_line, "", 1e8)
local ret = dofile(jLuaScript)
debug.sethook()
return ret
end
args = { ... }
if jthread == nil then
error("jthread object is nil. Please set it in the Java environment.",2)
elseif jLuaScript == nil then
error("jLuaScript not set. Please set it in the Java environment.",2)
else
local x,y = xpcall(inithook, debug.traceback)
end
Here's the ScriptState class that stores the flag and a main() to demonstrate:
public class ScriptState {
private AtomicBoolean isDone = new AtomicBoolean(true);
public boolean getDone() { return isDone.get(); }
public void setDone(boolean v) { isDone.set(v); }
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
System.out.println("J: Lua script started.");
ScriptState s = new ScriptState();
Globals g = JsePlatform.debugGlobals();
g.set("jLuaScript", "res/main.lua");
g.set("jthread", CoerceJavaToLua.coerce(s));
try {
g.loadFile("res/_interpreter.lua").call();
} catch (Exception e) {
System.err.println("There was a Lua error!");
e.printStackTrace();
}
}
};
t.start();
try { t.join(); } catch (Exception e) { System.err.println("Error waiting for thread"); }
System.out.println("J: End main");
}
}
res/main.lua contains the target Lua code to be run. Use environment variables or parameters to pass additional information to the script as usual. Remember to use JsePlatform.debugGlobals() instead of JsePlatform.standardGlobals() if you want to use the debug library in Lua.
EDIT: I just noticed that os.exit() not only terminates the Lua script but also the calling process. It seems to be the equivalent of System.exit(). error() will throw an error but will not cause the Lua script to terminate. I'm trying to find a solution for this now.
Thanks to #Seldon for suggesting the use of custom DebugLib. I implemented a simplified version of that by just checking before every instruction if a predefined amount of time is elapsed. This is of course not super accurate because there is some time between class creation and script execution. Requires no separate threads.
class DebugLibWithTimeout(
timeout: Duration,
) : DebugLib() {
private val timeoutOn = Instant.now() + timeout
override fun onInstruction(pc: Int, v: Varargs, top: Int) {
val timeoutElapsed = Instant.now() > timeoutOn
if (timeoutElapsed)
throw Exception("Timeout")
super.onInstruction(pc, v, top)
}
}
Important note: if you sandbox an untrusted script calling load function on Lua-code and passing a separate environment to it, this will not work. onInstruction() seems to be called only if the function environment is a reference to _G. I dealt with that by stripping everything from _G and then adding whitelisted items back.
-- whitelisted items
local sandbox_globals = {
print = print
}
local original_globals = {}
for key, value in pairs(_G) do
original_globals[key] = value
end
local sandbox_env = _G
-- Remove everything from _G
for key, _ in pairs(sandbox_env) do
sandbox_env[key] = nil
end
-- Add whitelisted items back.
-- Global pairs-function cannot be used now.
for key, value in original_globals.pairs(sandbox_globals) do
sandbox_env[key] = value
end
local function run_user_script(script)
local script_function, message = original_globals.load(script, nil, 't', sandbox_env)
if not script_function then
return false, message
end
return pcall(script_function)
end
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
The following code segment:
private class ConnectionControl implements Runnable
{
public void run()
{
while( true )
{
if( !cnnct.isInMsgEmpty() )
System.out.println( "Incoming message: " + cnnct.getInMsg().getPayloadString() ) ;
}
}
}
Works when I run it in eclipse debugger and place a breakpoint at the System.out line. However, if I run it normally I don't get the "Incoming message..." output.
Any thoughts on why this would be or how even to debug it???
Ahh figured it out... had a deadlock situation going on where two threads were using the same resource. Thanks for your help guys!
Cheers!
There are multiple ways to invoke Java code, depending on where you need it.
What you have shown is not enough to be self-standing, and should cause an error if you try to invoke it as an applet or a java application (java .... ConnectionControl). It may be that Eclipse can invoke a Runnable - I have not seen it though.
Try
making the class public
add a static main method making it a Java application
put a message in the start of the main method so you can see it is invoked
You're already using System.out.println for your program output. Add some sysouts that output where you are in the code and the status of various variables.
I don't know how this is being called but from the code I see your if condition is always evaluating false.
I created a method and keep getting an error that I need to include a } at the end of my method. I put the } in and the error is still there! If I then delete that } the same error will pop up on a prior method; and that error wasn't there before. in other words, if i type the } on my most recent method then the error stays there and only there. if i delete it, it duplicates that error on my prior method.
private void putThreeBeepers() {
for (int i = 0; i < 2; i++) {
putBeeper();
move();
}
putBeeper();
}
private void backUp() {
turnAround();
move();
turnAround();
}
You really want to go to the top of your file and do proper and consistent indention all the way to the bottom.
For example...
private void putThreeBeepers()
{
for (int i = 0; i < 2; i++) {
putBeeper();
move();
}
putBeeper();
}
private void backUp()
{
turnAround();
move();
turnAround();
}
Odds are, somewhere along the line, you are missing a }. Your description isn't super clear, but if the code you posted is how you actually have it formatted in your file then odds are you just missed something somewhere... and poor indentation makes it very hard to spot.
The fact that the message is changing is confusing, but it is the sort of thing you see in these cases.
the error might be misleading. In my case i had incorrect/incomplete comment statements such as below which is broken lead to this error:
/*
// */
*/
Fixing the comments fixed the error. Hope this helps. Thanks.
I think this can be caused by a number of different problems. :(
In my case it was that I have forgotten to specify the type of two parameters in one of my methods declareations.
To fix I had to change this:
onUpgrade(SQLiteDatabase pDb, pOldVersion, pNewVersion)
{
}
to this:
onUpgrade(SQLiteDatabase pDb, int pOldVersion, int pNewVersion)
It might be due to invisible Chars when copying code from PDF ebook.
Be careful of the little red dot '.'
Choose 'Select First Character' -> then delete it.
Also, the same error might occur if you accidentally write an if-statement outside of a method. I kept overlooking it since I was looking at the bracket-matching only.
I just simply add another"}",makes as "}}",then problem solved
I didnt have to put anther "}" for my other java code exercise.
Im a java beginner,I've come across same problem so I searched online found this thread.Hope this help
Had the same problem. Turned out to be a very fundamental oversight.
I was having the properties of a class declared like this:
private Texture foo;
private Sprite bar;
foo = new Texture();
bar = new Sprite();
The mistake was i had been instantiating the foo and bar variables outside the functions
of the class. When I put the
foo = new Texture();
bar = new Sprite();
into their proper functions (like below), the error went away.
private Texture foo;
private Sprite bar;
// function
public void instantiateVariables(){
foo = new Texture();
bar = new Sprite();
}
I got this error due to a missing <%.
Here are the steps.
Just copy paste your code in notepad
Remove copy from Java file
Again copy notepad and paste into Java file.
An error will be gone.
This question have already accepted answer but still there are some other problems where it occurs (like even though all statements are there correctly sometimes we will get this issue) and there are solutions too.
Recently I came across like this situation in eclipse workspace.
The solution is
Take the back up of that java file.
Remove the java file from that location and do the build/compile
Paste the file in the same location and do the build/compile
If the above step 3 does not work create new file and paste the content/code from backup file and do the build/compile
If the above step 3&4 both are not working then type the code of that file manually end-to-end and do the build/compile
If this error comes in jsp, look for the braces. if open or close braces are missing, we will get this error.