Why do I lose the console output? - java

I have this code in a JUnit Test :
public class CvsCommandTest {
...
#Test
public void test() {
PServerConnection con = new PServerConnection(root);
GlobalOptions globalOptions = new GlobalOptions();
globalOptions.setCVSRoot(root.toString());
Client client = new Client(con, new StandardAdminHandler());
client.setLocalPath(LOCAL_PATH);
client.getEventManager().addCVSListener(new BasicListener());
CheckoutCommand checkoutCmd = new CheckoutCommand();
checkoutCmd.setBuilder(null);
checkoutCmd.setModule("Outils");
try {
client.getConnection().open();
LOG.info("CVS checkout : " + checkoutCmd.getCVSCommand());
boolean successCheckout = client.executeCommand(checkoutCmd,globalOptions );
LOG.info("Checkout COMPLETED : " + successCheckout);
...
The output, while debugging, is :
[INFO] fr.package.CvsCommandTest - CVS checkout : checkout
-N Outils
cvs checkout: Updating Outils
The first line is my log, the second comes from the listener but I don't get the remaining of my logs.
The basicListener is defined this way :
import java.io.PrintStream;
import org.netbeans.lib.cvsclient.event.CVSAdapter;
import org.netbeans.lib.cvsclient.event.MessageEvent;
public class BasicListener extends CVSAdapter {
/** * Stores a tagged line */
private final StringBuffer taggedLine = new StringBuffer();
/**
* Called when the server wants to send a message to be displayed to the
* user. The message is only for information purposes and clients can choose
* to ignore these messages if they wish.
*
* #param e
* the event
*/
public void messageSent(MessageEvent e) {
String line = e.getMessage();
PrintStream stream = e.isError() ? System.err : System.out;
if (e.isTagged()) {
String message = MessageEvent.parseTaggedMessage(taggedLine, line);
if (message != null) {
stream.println(message);
}
} else {
stream.println(line);
}
stream.close();
}
}
What have I missed?

Turned comment in to answer
System.out stream.close(); --> good night...
Explanation:
Since he is using the System.out to output he's log message when he close the System.out #see end of public void messageSent(MessageEvent e) ,stream.close(); the System.out is closed and can not be used anymore, so good night to System.out
The solution is:
Removing the stream.close(); command

Related

virtual machine object cannot find or load Main class

so i have problem where i am trying to open a file through my own written virtual machine object in java but the problem is that the virtual machine is not running and causing an error.
Error: Could not find or load main class C:\Users\dell\Trace\Main.java
we also tried modifying the CLASSPATH & PATH with no success
below is the code of the main
import com.sun.jdi.Bootstrap;
import com.sun.jdi.connect.*;
import java.util.Map;
import java.util.List;
import java.util.Iterator;
import java.io.PrintWriter;
import java.io.FileWriter;
import java.io.IOException;
public class Trace {
// Running remote VM
private final VirtualMachine vm;
// Thread transferring remote error stream to our error stream
private Thread errThread = null;
// Thread transferring remote output stream to our output stream
private Thread outThread = null;
// Mode for tracing the Trace program (default= 0 off)
private int debugTraceMode = 0;
// Do we want to watch assignments to fields
private boolean watchFields = false;
// Class patterns for which we don't want events
private String[] excludes = {"java.*", "javax.*", "sun.*",
"com.sun.*"};
/**
* main
*/
public static void main(String[] args) {
new Trace(args);
}
/**
* Parse the command line arguments.
* Launch target VM.
* Generate the trace.
*/
Trace(String[] args) {
PrintWriter writer = new PrintWriter(System.out);
int inx;
for (inx = 0; inx < args.length; ++inx) {
String arg = args[inx];
if (arg.charAt(0) != '-') {
break;
}
if (arg.equals("-output")) {
try {
writer = new PrintWriter(new FileWriter(args[++inx]));
} catch (IOException exc) {
System.err.println("Cannot open output file: " + args[inx]
+ " - " + exc);
System.exit(1);
}
} else if (arg.equals("-all")) {
excludes = new String[0];
} else if (arg.equals("-fields")) {
watchFields = true;
} else if (arg.equals("-dbgtrace")) {
debugTraceMode = Integer.parseInt(args[++inx]);
} else if (arg.equals("-help")) {
usage();
System.exit(0);
} else {
System.err.println("No option: " + arg);
usage();
System.exit(1);
}
}
if (inx >= args.length) {
System.err.println("<class> missing");
usage();
System.exit(1);
}
StringBuffer sb = new StringBuffer();
sb.append(args[inx]);
for (++inx; inx < args.length; ++inx) {
sb.append(' ');
sb.append(args[inx]);
}
vm = launchTarget(sb.toString());
generateTrace(writer);
}
/**
* Generate the trace.
* Enable events, start thread to display events,
* start threads to forward remote error and output streams,
* resume the remote VM, wait for the final event, and shutdown.
*/
void generateTrace(PrintWriter writer) {
vm.setDebugTraceMode(debugTraceMode);
EventThread eventThread = new EventThread(vm, excludes, writer);
eventThread.setEventRequests(watchFields);
eventThread.start();
redirectOutput();
vm.resume();
// Shutdown begins when event thread terminates
try {
eventThread.join();
errThread.join(); // Make sure output is forwarded
outThread.join(); // before we exit
} catch (InterruptedException exc) {
// we don't interrupt
}
writer.close();
}
/**
* Launch target VM.
* Forward target's output and error.
*/
VirtualMachine launchTarget(String mainArgs) {
LaunchingConnector connector = findLaunchingConnector();
Map arguments = connectorArguments(connector, mainArgs);
try {
return connector.launch(arguments);
} catch (IOException exc) {
throw new Error("Unable to launch target VM: " + exc);
} catch (IllegalConnectorArgumentsException exc) {
throw new Error("Internal error: " + exc);
} catch (VMStartException exc) {
throw new Error("Target VM failed to initialize: " +
exc.getMessage());
}
}
void redirectOutput() {
Process process = vm.process();
// Copy target's output and error to our output and error.
errThread = new StreamRedirectThread("error reader",
process.getErrorStream(),
System.err);
outThread = new StreamRedirectThread("output reader",
process.getInputStream(),
System.out);
errThread.start();
outThread.start();
}
/**
* Find a com.sun.jdi.CommandLineLaunch connector
*/
LaunchingConnector findLaunchingConnector() {
List connectors = Bootstrap.virtualMachineManager().allConnectors();
Iterator iter = connectors.iterator();
while (iter.hasNext()) {
Connector connector = (Connector)iter.next();
if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) {
return (LaunchingConnector)connector;
}
}
throw new Error("No launching connector");
}
/**
* Return the launching connector's arguments.
*/
Map connectorArguments(LaunchingConnector connector, String mainArgs) {
Map arguments = connector.defaultArguments();
Connector.Argument mainArg =
(Connector.Argument)arguments.get("main");
if (mainArg == null) {
throw new Error("Bad launching connector");
}
mainArg.setValue(mainArgs);
if (watchFields) {
// We need a VM that supports watchpoints
Connector.Argument optionArg =
(Connector.Argument)arguments.get("options");
if (optionArg == null) {
throw new Error("Bad launching connector");
}
optionArg.setValue("-classic");
}
return arguments;
}
/**
* Print command line usage help
*/
void usage() {
System.err.println("Usage: java Trace <options> <class> <args>");
System.err.println("<options> are:");
System.err.println(
" -output <filename> Output trace to <filename>");
System.err.println(
" -all Include system classes in output");
System.err.println(
" -help Print this help message");
System.err.println("<class> is the program to trace");
System.err.println("<args> are the arguments to <class>");
}
}

Force stop Java Files.copy() running on external thread

The answer here seemed to be a valid solution before Java 8:
How to cancel Files.copy() in Java?
But now it doesn't work, because ExtendedCopyOption.INTERRUPTIBLE is private.
Basically, I need to download a file from some given URL and save it to my local file-system using Files.copy().
Currently, I am using a JavaFX Service because I need to show the progress in a ProgressBar.
However, I don't know how to block the thread running Files.copy() if the operation takes too long.
Using Thread.stop() is at least not wanted. Even Thread.interrupt() fails.
I also want the operation to terminate gracefully if the internet connection becomes unavailable.
To test the case when no internet connection is available, I'm removing my ethernet cable and putting it back after 3 seconds.
Unfortunately, Files.copy() returns only when I put back the ethernet cable, while I would like it to fail immediately.
As I can see, internally Files.copy() is running a loop, which prevents the thread from exiting.
Tester(Downloading OBS Studio exe):
/**
* #author GOXR3PLUS
*
*/
public class TestDownloader extends Application {
/**
* #param args
*/
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
// Block From exiting
Platform.setImplicitExit(false);
// Try to download the File from URL
new DownloadService().startDownload(
"https://github.com/jp9000/obs-studio/releases/download/17.0.2/OBS-Studio-17.0.2-Small-Installer.exe",
System.getProperty("user.home") + File.separator + "Desktop" + File.separator + "OBS-Studio-17.0.2-Small-Installer.exe");
}
}
DownloadService:
Using #sillyfly comment with FileChannel and removing File.copy seems to work only with calling Thread.interrupt() but it is not exiting when the internet is not available..
import java.io.File;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
/**
* JavaFX Service which is Capable of Downloading Files from the Internet to the
* LocalHost
*
* #author GOXR3PLUS
*
*/
public class DownloadService extends Service<Boolean> {
// -----
private long totalBytes;
private boolean succeeded = false;
private volatile boolean stopThread;
// CopyThread
private Thread copyThread = null;
// ----
private String urlString;
private String destination;
/**
* The logger of the class
*/
private static final Logger LOGGER = Logger.getLogger(DownloadService.class.getName());
/**
* Constructor
*/
public DownloadService() {
setOnFailed(f -> System.out.println("Failed with value: " + super.getValue()+" , Copy Thread is Alive? "+copyThread.isAlive()));
setOnSucceeded(s -> System.out.println("Succeeded with value: " + super.getValue()+" , Copy Thread is Alive? "+copyThread.isAlive()));
setOnCancelled(c -> System.out.println("Succeeded with value: " + super.getValue()+" , Copy Thread is Alive? "+copyThread.isAlive()));
}
/**
* Start the Download Service
*
* #param urlString
* The source File URL
* #param destination
* The destination File
*/
public void startDownload(String urlString, String destination) {
if (!super.isRunning()) {
this.urlString = urlString;
this.destination = destination;
totalBytes = 0;
restart();
}
}
#Override
protected Task<Boolean> createTask() {
return new Task<Boolean>() {
#Override
protected Boolean call() throws Exception {
// Succeeded boolean
succeeded = true;
// URL and LocalFile
URL urlFile = new URL(java.net.URLDecoder.decode(urlString, "UTF-8"));
File destinationFile = new File(destination);
try {
// Open the connection and get totalBytes
URLConnection connection = urlFile.openConnection();
totalBytes = Long.parseLong(connection.getHeaderField("Content-Length"));
// --------------------- Copy the File to External Thread-----------
copyThread = new Thread(() -> {
// Start File Copy
try (FileChannel zip = FileChannel.open(destinationFile.toPath(), StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)) {
zip.transferFrom(Channels.newChannel(connection.getInputStream()), 0, Long.MAX_VALUE);
// Files.copy(dl.openStream(), fl.toPath(),StandardCopyOption.REPLACE_EXISTING)
} catch (Exception ex) {
stopThread = true;
LOGGER.log(Level.WARNING, "DownloadService failed", ex);
}
System.out.println("Copy Thread exited...");
});
// Set to Daemon
copyThread.setDaemon(true);
// Start the Thread
copyThread.start();
// -------------------- End of Copy the File to External Thread-------
// ---------------------------Check the %100 Progress--------------------
long outPutFileLength;
long previousLength = 0;
int failCounter = 0;
// While Loop
while ((outPutFileLength = destinationFile.length()) < totalBytes && !stopThread) {
// Check the previous length
if (previousLength != outPutFileLength) {
previousLength = outPutFileLength;
failCounter = 0;
} else
++failCounter;
// 2 Seconds passed without response
if (failCounter == 40 || stopThread)
break;
// Update Progress
super.updateProgress((outPutFileLength * 100) / totalBytes, 100);
System.out.println("Current Bytes:" + outPutFileLength + " ,|, TotalBytes:" + totalBytes
+ " ,|, Current Progress: " + (outPutFileLength * 100) / totalBytes + " %");
// Sleep
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
LOGGER.log(Level.WARNING, "", ex);
}
}
// 2 Seconds passed without response
if (failCounter == 40)
succeeded = false;
// --------------------------End of Check the %100 Progress--------------------
} catch (Exception ex) {
succeeded = false;
// Stop the External Thread which is updating the %100
// progress
stopThread = true;
LOGGER.log(Level.WARNING, "DownloadService failed", ex);
}
//----------------------Finally------------------------------
System.out.println("Trying to interrupt[shoot with an assault rifle] the copy Thread");
// ---FORCE STOP COPY FILES
if (copyThread != null && copyThread.isAlive()) {
copyThread.interrupt();
System.out.println("Done an interrupt to the copy Thread");
// Run a Looping checking if the copyThread has stopped...
while (copyThread.isAlive()) {
System.out.println("Copy Thread is still Alive,refusing to die.");
Thread.sleep(50);
}
}
System.out.println("Download Service exited:[Value=" + succeeded + "] Copy Thread is Alive? "
+ (copyThread == null ? "" : copyThread.isAlive()));
//---------------------- End of Finally------------------------------
return succeeded;
}
};
}
}
Interesting questions:
1-> What does java.lang.Thread.interrupt() do?
I strongly encourage you to use a FileChannel.
It has the transferFrom() method which returns immediately when the thread running it is interrupted.
(The Javadoc here says that it should raise a ClosedByInterruptException, but it doesn't.)
try (FileChannel channel = FileChannel.open(Paths.get(...), StandardOpenOption.CREATE,
StandardOpenOption.WRITE)) {
channel.transferFrom(Channels.newChannel(new URL(...).openStream()), 0, Long.MAX_VALUE);
}
It also has the potential to perform much better than its java.io alternative.
(However, it turns out that the implementation of Files.copy() may elect to delegate to this method instead of actually performing the copy by itself.)
Here's an example of a reusable JavaFX Service that lets you fetch a resource from the internet and save it to your local file-system, with automatic graceful termination if the operation takes too long.
The service task (spawned by createTask()) is the user of the file-channel API.
A separate ScheduledExecutorService is used to handle the time constraint.
Always stick to the good practices for extending Service.
If you choose to use such an high-level method, you won't be able to track down the progress of the task.
If the connection becomes unavailable, transferFrom() should eventually return without throwing an exception.
To start the service (may be done from any thread):
DownloadService downloadService = new DownloadService();
downloadService.setRemoteResourceLocation(new URL("http://speedtest.ftp.otenet.gr/files/test1Gb.db"));
downloadService.setPathToLocalResource(Paths.get("C:", "test1Gb.db"));
downloadService.start();
and then to cancel it (otherwise it will be automatically cancelled after the time expires):
downloadService.cancel();
Note that the same service can be reused, just be sure to reset it before starting again:
downloadService.reset();
Here is the DownloadService class:
public class DownloadService extends Service<Void> {
private static final long TIME_BUDGET = 2; // In seconds
private final ScheduledExecutorService watchdogService =
Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
private final ThreadFactory delegate = Executors.defaultThreadFactory();
#Override
public Thread newThread(Runnable r) {
Thread thread = delegate.newThread(r);
thread.setDaemon(true);
return thread;
}
});
private Future<?> watchdogThread;
private final ObjectProperty<URL> remoteResourceLocation = new SimpleObjectProperty<>();
private final ObjectProperty<Path> pathToLocalResource = new SimpleObjectProperty<>();
public final URL getRemoteResourceLocation() {
return remoteResourceLocation.get();
}
public final void setRemoteResourceLocation(URL remoteResourceLocation) {
this.remoteResourceLocation.set(remoteResourceLocation);
}
public ObjectProperty<URL> remoteResourceLocationProperty() {
return remoteResourceLocation;
}
public final Path getPathToLocalResource() {
return pathToLocalResource.get();
}
public final void setPathToLocalResource(Path pathToLocalResource) {
this.pathToLocalResource.set(pathToLocalResource);
}
public ObjectProperty<Path> pathToLocalResourceProperty() {
return pathToLocalResource;
}
#Override
protected Task<Void> createTask() {
final Path pathToLocalResource = getPathToLocalResource();
final URL remoteResourceLocation = getRemoteResourceLocation();
if (pathToLocalResource == null) {
throw new IllegalStateException("pathToLocalResource property value is null");
}
if (remoteResourceLocation == null) {
throw new IllegalStateException("remoteResourceLocation property value is null");
}
return new Task<Void>() {
#Override
protected Void call() throws IOException {
try (FileChannel channel = FileChannel.open(pathToLocalResource, StandardOpenOption.CREATE,
StandardOpenOption.WRITE)) {
channel.transferFrom(Channels.newChannel(remoteResourceLocation.openStream()), 0, Long.MAX_VALUE);
}
return null;
}
};
}
#Override
protected void running() {
watchdogThread = watchdogService.schedule(() -> {
Platform.runLater(() -> cancel());
}, TIME_BUDGET, TimeUnit.SECONDS);
}
#Override
protected void succeeded() {
watchdogThread.cancel(false);
}
#Override
protected void cancelled() {
watchdogThread.cancel(false);
}
#Override
protected void failed() {
watchdogThread.cancel(false);
}
}
There is one important aspect not covered by the other answers/comments; and that is a wrong assumption of yours:
What I want is it to fail immediately when no internet connection is there.
It is not that easy. The TCP stack/state machine is actually a pretty complicated thing; and depending on your context (OS type; TCP stack implementation, kernel parameters, ...), there can be situations where a network partition takes place and a sender doesn't notice for 15 or more minutes. Listen here for more details on that.
In other words: "just pulling the plug" is no way equal to "immediately breaking" your existing TCP connection. And just for the record: you don't need to plug cables manually to simulate network outages. In a reasonable test setup, tools like iptables aka firewalls can do that for you.
You seem to need an Asynchronous/Cancellable HTTP GET which can be tough.
The problem is that if read stalls waiting for more data (cable is pulled) it won't quit until either the socket dies or new data comes in.
There are a few path you could follow, tinkering with socket factories to set a good timeout, using http client with timeouts and others.
I would have a look at Apache Http Components which has non blocking HTTP based on java NIO Sockets.

Gracefully ending a thread that's waiting on a blocking queue

I'm having an issue with a multi-threaded server I'm building as an academic exercise, more specifically with getting a connection to close down gracefully.
Each connection is managed by a Session class. This class maintains 2 threads for the connection, a DownstreamThread and an UpstreamThread.
The UpstreamThread blocks on the client socket and encodes all incoming strings into messages to be passed up to another layer to deal with. The DownstreamThread blocks on a BlockingQueue into which messages for the client are inserted. When there's a message on the queue, the Downstream thread takes the message off the queue, turns it into a string and sends it to the client. In the final system, an application layer will act on incoming messages and push outgoing messages down to the server to send to the appropriate client, but for now I just have a simple application that sleeps for a second on an incoming message before echoing it back as an outgoing message with a timestamp appended.
The problem I'm having is getting the whole thing to shut down gracefully when the client disconnects. The first issue I'm contending with is a normal disconnect, where the client lets the server know that it's ending the connection with a QUIT command. The basic pseudocode is:
while (!quitting) {
inputString = socket.readLine () // blocks
if (inputString != "QUIT") {
// forward the message upstream
server.acceptMessage (inputString);
} else {
// Do cleanup
quitting = true;
socket.close ();
}
}
The upstream thread's main loop looks at the input string. If it's QUIT the thread sets a flag to say that the client has ended communications and exits the loop. This leads to the upstream thread shutting down nicely.
The downstream thread's main loop waits for messages in the BlockingQueue for as long as the connection closing flag isn't set. When it is, the downstream thread is also supposed to terminate. However, it doesn't, it just sits there waiting. Its psuedocode looks like this:
while (!quitting) {
outputMessage = messageQueue.take (); // blocks
sendMessageToClient (outputMessage);
}
When I tested this, I noticed that when the client quit, the upstream thread shut down, but the downstream thread didn't.
After a bit of head scratching, I realised that the downstream thread is still blocking on the BlockingQueue waiting for an incoming message that will never come. The upstream thread doesn't forward the QUIT message any further up the chain.
How can I make the downstream thread shut down gracefully? The first idea that sprang to mind was setting a timeout on the take() call. I'm not too keen on this idea though, because whatever value you select, it's bound to be not entirely satisfactory. Either it's too long and a zombie thread sits there for a long time before shutting down, or it's too short and connections that have idled for a few minutes but are still valid will be killed. I did think of sending the QUIT message up the chain, but that requires it to make a full round trip to the server, then the application, then back down to the server again and finally to the session. This doesn't seem like an elegant solution either.
I did look at the documentation for Thread.stop() but that's apparently deprecated because it never worked properly anyway, so that looks like it's not really an option either. Another idea I had was to force an exception to be triggered in the downstream thread somehow and let it clean up in its finally block, but this strikes me as a horrible and kludgey idea.
I feel that both threads should be able to gracefully shutdown on their own, but I also suspect that if one thread ends it must also signal the other thread to end in a more proactive way than simply setting a flag for the other thread to check. As I'm still not very experienced with Java, I'm rather out of ideas at this point. If anyone has any advice, it would be greatly appreciated.
For the sake of completeness, I've included the real code for the Session class below, though I believe the pseudocode snippets above cover the relevant parts of the problem. The full class is about 250 lines.
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
import java.util.logging.*;
/**
* Session class
*
* A session manages the individual connection between a client and the server.
* It accepts input from the client and sends output to the client over the
* provided socket.
*
*/
public class Session {
private Socket clientSocket = null;
private Server server = null;
private Integer sessionId = 0;
private DownstreamThread downstream = null;
private UpstreamThread upstream = null;
private boolean sessionEnding = false;
/**
* This thread handles waiting for messages from the server and sending
* them to the client
*/
private class DownstreamThread implements Runnable {
private BlockingQueue<DownstreamMessage> incomingMessages = null;
private OutputStreamWriter streamWriter = null;
private Session outer = null;
#Override
public void run () {
DownstreamMessage message;
Thread.currentThread ().setName ("DownstreamThread_" + outer.getId ());
try {
// Send connect message
this.sendMessageToClient ("Hello, you are client " + outer.getId ());
while (!outer.sessionEnding) {
message = this.incomingMessages.take ();
this.sendMessageToClient (message.getPayload ());
}
// Send disconnect message
this.sendMessageToClient ("Goodbye, client " + getId ());
} catch (InterruptedException | IOException ex) {
Logger.getLogger (DownstreamThread.class.getName ()).log (Level.SEVERE, ex.getMessage (), ex);
} finally {
this.terminate ();
}
}
/**
* Add a message to the downstream queue
*
* #param message
* #return
* #throws InterruptedException
*/
public DownstreamThread acceptMessage (DownstreamMessage message) throws InterruptedException {
if (!outer.sessionEnding) {
this.incomingMessages.put (message);
}
return this;
}
/**
* Send the given message to the client
*
* #param message
* #throws IOException
*/
private DownstreamThread sendMessageToClient (CharSequence message) throws IOException {
OutputStreamWriter osw;
// Output to client
if (null != (osw = this.getStreamWriter ())) {
osw.write ((String) message);
osw.write ("\r\n");
osw.flush ();
}
return this;
}
/**
* Perform session cleanup
*
* #return
*/
private DownstreamThread terminate () {
try {
this.streamWriter.close ();
} catch (IOException ex) {
Logger.getLogger (DownstreamThread.class.getName ()).log (Level.SEVERE, ex.getMessage (), ex);
}
this.streamWriter = null;
return this;
}
/**
* Get an output stream writer, initialize it if it's not active
*
* #return A configured OutputStreamWriter object
* #throws IOException
*/
private OutputStreamWriter getStreamWriter () throws IOException {
if ((null == this.streamWriter)
&& (!outer.sessionEnding)) {
BufferedOutputStream os = new BufferedOutputStream (outer.clientSocket.getOutputStream ());
this.streamWriter = new OutputStreamWriter (os, "UTF8");
}
return this.streamWriter;
}
/**
*
* #param outer
*/
public DownstreamThread (Session outer) {
this.outer = outer;
this.incomingMessages = new LinkedBlockingQueue ();
System.out.println ("Class " + this.getClass () + " created");
}
}
/**
* This thread handles waiting for client input and sending it upstream
*/
private class UpstreamThread implements Runnable {
private Session outer = null;
#Override
public void run () {
StringBuffer inputBuffer = new StringBuffer ();
BufferedReader inReader;
Thread.currentThread ().setName ("UpstreamThread_" + outer.getId ());
try {
inReader = new BufferedReader (new InputStreamReader (outer.clientSocket.getInputStream (), "UTF8"));
while (!outer.sessionEnding) {
// Read whatever was in the input buffer
inputBuffer.delete (0, inputBuffer.length ());
inputBuffer.append (inReader.readLine ());
System.out.println ("Input message was: " + inputBuffer);
if (!inputBuffer.toString ().equals ("QUIT")) {
// Forward the message up the chain to the Server
outer.server.acceptMessage (new UpstreamMessage (sessionId, inputBuffer.toString ()));
} else {
// End the session
outer.sessionEnding = true;
}
}
} catch (IOException | InterruptedException e) {
Logger.getLogger (Session.class.getName ()).log (Level.SEVERE, e.getMessage (), e);
} finally {
outer.terminate ();
outer.server.deleteSession (outer.getId ());
}
}
/**
* Class constructor
*
* The Core Java volume 1 book said that a constructor such as this
* should be implicitly created, but that doesn't seem to be the case!
*
* #param outer
*/
public UpstreamThread (Session outer) {
this.outer = outer;
System.out.println ("Class " + this.getClass () + " created");
}
}
/**
* Start the session threads
*/
public void run () //throws InterruptedException
{
Thread upThread = new Thread (this.upstream);
Thread downThread = new Thread (this.downstream);
upThread.start ();
downThread.start ();
}
/**
* Accept a message to send to the client
*
* #param message
* #return
* #throws InterruptedException
*/
public Session acceptMessage (DownstreamMessage message) throws InterruptedException {
this.downstream.acceptMessage (message);
return this;
}
/**
* Accept a message to send to the client
*
* #param message
* #return
* #throws InterruptedException
*/
public Session acceptMessage (String message) throws InterruptedException {
return this.acceptMessage (new DownstreamMessage (this.getId (), message));
}
/**
* Terminate the client connection
*/
private void terminate () {
try {
this.clientSocket.close ();
} catch (IOException e) {
Logger.getLogger (Session.class.getName ()).log (Level.SEVERE, e.getMessage (), e);
}
}
/**
* Get this Session's ID
*
* #return The ID of this session
*/
public Integer getId () {
return this.sessionId;
}
/**
* Session constructor
*
* #param owner The Server object that owns this session
* #param sessionId The unique ID this session will be given
* #throws IOException
*/
public Session (Server owner, Socket clientSocket, Integer sessionId) throws IOException {
this.server = owner;
this.clientSocket = clientSocket;
this.sessionId = sessionId;
this.upstream = new UpstreamThread (this);
this.downstream = new DownstreamThread (this);
System.out.println ("Class " + this.getClass () + " created");
System.out.println ("Session ID is " + this.sessionId);
}
}
Instead of calling Thread.stop use Thread.interrupt. That will cause the take method to throw an InterruptedException which you can use to know that you should shut down.
Can you just create "fake" quit message instead of setting outer.sessionEnding to true when "QUIT" appears. Putting this fake message in queue will wake the DownstreamThread and you can end it. In that case you can even eliminate this sessionEnding variable.
In pseudo code this could look like this:
while (true) {
outputMessage = messageQueue.take (); // blocks
if (QUIT == outputMessage)
break
sendMessageToClient (outputMessage);
}

Problem in java programming on windows7 (working well in windows xp)

I am capturing video from webcam connected to pc.I am using the following code to do so:
import java.util.*;
import javax.media.*;
import javax.media.protocol.*;
import javax.media.control.*;
import javax.media.format.*;
import java.awt.*;
/**
* This is the primary class to run. It gathers an image stream and drives the processing.
*
*/
public class jmfcam05v
{
DataSource dataSource;
PushBufferStream pbs;
Vector camImgSize = new Vector();
Vector camCapDevice = new Vector();
Vector camCapFormat = new Vector();
int camFPS;
int camImgSel;
Processor processor = null;
DataSink datasink = null;
/**
* Main method to instance and run class
*
*/
public static void main(String[] args)
{
jmfcam05v jmfcam = new jmfcam05v();
}
/**
* Constructor and processing method for image stream from a cam
*
*/
public jmfcam05v()
{
// Select webcam format
fetchDeviceFormats();
camImgSel=0; // first format, or otherwise as desired
camFPS = 20; // framerate
// Setup data source
fetchDeviceDataSource();
createPBDSource();
createProcessor(dataSource);
startCapture();
try{Thread.sleep(90000);}catch(Exception e){} // 20 seconds
stopCapture();
}
/**
* Gathers info on a camera
*
*/
boolean fetchDeviceFormats()
{
Vector deviceList = CaptureDeviceManager.getDeviceList(new VideoFormat(null));
CaptureDeviceInfo CapDevice = null;
Format CapFormat = null;
String type = "N/A";
CaptureDeviceInfo deviceInfo=null;boolean VideoFormatMatch=false;
for(int i=0;i<deviceList.size();i++)
{
// search for video device
deviceInfo = (CaptureDeviceInfo)deviceList.elementAt(i);
if(deviceInfo.getName().indexOf("vfw:")<0)continue;
Format deviceFormat[] = deviceInfo.getFormats();
for (int f=0;f<deviceFormat.length;f++)
{
if(deviceFormat[f] instanceof RGBFormat)type="RGB";
if(deviceFormat[f] instanceof YUVFormat)type="YUV";
if(deviceFormat[f] instanceof JPEGFormat)type="JPG";
Dimension size = ((VideoFormat)deviceFormat[f]).getSize();
camImgSize.addElement(type+" "+size.width+"x"+size.height);
CapDevice = deviceInfo;
camCapDevice.addElement(CapDevice);
//System.out.println("Video device = " + deviceInfo.getName());
CapFormat = (VideoFormat)deviceFormat[f];
camCapFormat.addElement(CapFormat);
//System.out.println("Video format = " + deviceFormat[f].toString());
VideoFormatMatch=true; // at least one
}
}
if(VideoFormatMatch==false)
{
if(deviceInfo!=null)System.out.println(deviceInfo);
System.out.println("Video Format not found");
return false;
}
return true;
}
/**
* Finds a camera and sets it up
*
*/
void fetchDeviceDataSource()
{
CaptureDeviceInfo CapDevice = (CaptureDeviceInfo)camCapDevice.elementAt(camImgSel);
System.out.println("Video device = " + CapDevice.getName());
Format CapFormat = (Format)camCapFormat.elementAt(camImgSel);
System.out.println("Video format = " + CapFormat.toString());
MediaLocator loc = CapDevice.getLocator();
try
{
dataSource = Manager.createDataSource(loc);
}
catch(Exception e){}
try
{
// ensures 30 fps or as otherwise preferred, subject to available cam rates but this is frequency of windows request to stream
FormatControl formCont=((CaptureDevice)dataSource).getFormatControls()[0];
VideoFormat formatVideoNew = new VideoFormat(null,null,-1,null,(float)camFPS);
formCont.setFormat(CapFormat.intersects(formatVideoNew));
}
catch(Exception e){}
}
/**
* Gets a stream from the camera (and sets debug)
*
*/
void createPBDSource()
{
try
{
pbs=((PushBufferDataSource)dataSource).getStreams()[0];
}
catch(Exception e){}
}
public void createProcessor(DataSource datasource)
{
FileTypeDescriptor ftd = new FileTypeDescriptor(FileTypeDescriptor.MSVIDEO);
Format[] formats = new Format[] {new VideoFormat(VideoFormat.INDEO50)};
ProcessorModel pm = new ProcessorModel(datasource, formats, ftd);
try
{
processor = Manager.createRealizedProcessor(pm);
}
catch(Exception me)
{
System.out.println(me);
// Make sure the capture devices are released
datasource.disconnect();
return;
}
}
private void startCapture()
{
// Get the processor's output, create a DataSink and connect the two.
DataSource outputDS = processor.getDataOutput();
try
{
MediaLocator ml = new MediaLocator("file:capture.avi");
datasink = Manager.createDataSink(outputDS, ml);
datasink.open();
datasink.start();
}catch (Exception e)
{
System.out.println(e);
}
processor.start();
System.out.println("Started saving...");
}
private void pauseCapture()
{
processor.stop();
}
private void resumeCapture()
{
processor.start();
}
private void stopCapture()
{
// Stop the capture and the file writer (DataSink)
processor.stop();
processor.close();
datasink.close();
processor = null;
System.out.println("Done saving.");
}
}
this program works well on windows xp(desktop) and wen i try to use it on windows7(laptop) it gives me the following error:
run: Video Format not found
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
at java.util.Vector.elementAt(Vector.java:427)
at jmfcam05v.fetchDeviceDataSource(jmfcam05v.java:112)
at jmfcam05v.<init>(jmfcam05v.java:49)
at jmfcam05v.main(jmfcam05v.java:34) Java Result: 1 BUILD SUCCESSFUL (total time: 0 seconds)
my program is not detectin my inbuild webcam on laptop nor it is detecting external web cam.i am using jmf to capture the video and all my webcam's are vfw supported.
Please help me to solve this issue.
Are you mixing 32 and 64-bit installs? I had a similar problem under Windows 7, and it was due to 64-bit incompatibilities between Windows 7, JRE and JMF. In short, JMF is only 32-bit and won't recognize devices if your JRE is 64-bit.
After following these instructions, I was able to recognize my camera and avoid the "Video Format not found" as well as the jmfstudio not detecting the video capture device.
Is it possible that Windows 7 security is preventing you from accessing the device, thus your list shows up as empty from your fetchDeviceDataSource() call.
You can try turning off UAC and see if it fixes your problem.

Java to batch file

try {
String comd ="E:/ior1.txt";
Runtime rt = Runtime.getRuntime();
rt.exec("C:/tes1.bat"+comd+"");
System.out.println("Process exitValue: ");
}
catch (Exception e)
{
System.out.println("Unexpected exception Trying to Execute Job: " +e);
}
But when I run I get an exception like this
Unexpected exception Trying to Execute Job: java.io.IOException: CreateProcess:
C:/tes1.batE:/ior1.txt error=2
Press any key to continue . . .
This is the batch file content
echo "testing"
echo %1
There's a blank missing after .bat (in the rt.exec line)
Edit:
You could also try executing:
rt.exec("cmd /c c:/tes1.bat "+comd);
Try prefixing the exec call with cmd /c or call, e.g.
rt.exec("cmd /c c:/tes1.bat "+comd);
(I don't have a Windows box available right now so I can't test this but as far as I remember, launching batch files required launching the command interpreter first.)
When i see this correct, you have to put a space between the bat command and the argument
EDIT:
try {
String comd ="E:/ior1.txt";
Runtime rt = Runtime.getRuntime();
rt.exec("C:/tes1.bat "+comd+"");
System.out.println("Process exitValue: ");
}
catch (Exception e)
{
System.out.println("Unexpected exception Trying to Execute Job: " +e);
}
EDIT 2:
After taking a look again and testing on my PC the other answers seems correct. The cmd is missing.
rt.exec("cmd /c c:/tes1.bat "+comd);
Be aware, that there is a number of issues related to executing an external process from within your Java program if you have to use this in a production environment.
You have e.g. to be aware of the fact, that if the output from the process is larger than the buffer used by the JVM<->OS the exec will block forever.
I normally use a wrapper with Threads to read from the buffers.
Its not perfect, but something like (see main() for details on usage):
/**
* Executes a given OS dependent command in a given directory with a given environment.
* The parameters are given at construction time and the initialized object is immutable.
* After the object initialization and execution of the blocking exec() method the state
* can't be changed. The result of the execution can be accessed through the get methods
* for the exitValue, stdOut, and stdErr properties. Before the exec() method is completed
* the excuted property is false and the result of other getters is undefined (null).
*/
public class CommandExecutor {
/**
* Specifies the number of times the termination of the process is
* waited for if the OS gives interruptions
*/
public static final int NUMBER_OF_RUNS = 2;
/**
* Used for testing and as example of usage.
*/
public static void main(String[] args) {
System.out.println("CommandExecutor.main Testing Begin");
String command_01 = "cmd.exe /C dir";
File dir_01 = new File("C:\\");
System.out.println("CommandExecutor.main Testing. Input: ");
System.out.println("CommandExecutor.main Testing. command: " + command_01);
System.out.println("CommandExecutor.main Testing. dir: " + dir_01);
CommandExecutor ce_01 = new CommandExecutor(command_01, null, dir_01);
ce_01.exec();
System.out.println("CommandExecutor.main Testing. Output:");
System.out.println(" exitValue: " + ce_01.getExitValue());
System.out.println(" stdout: " + ce_01.getStdout());
System.out.println(" stderr: " + ce_01.getStderr());
String command_02 = "cmd.exe /C dirs";
File dir_02 = new File("C:\\");
System.out.println("CommandExecutor.main Testing. Input: ");
System.out.println("CommandExecutor.main Testing. command: " + command_02);
System.out.println("CommandExecutor.main Testing. dir: " + dir_02);
CommandExecutor ce_02 = new CommandExecutor(command_02, null, dir_02);
ce_02.exec();
System.out.println("CommandExecutor.main Testing. Output:");
System.out.println(" exitValue: " + ce_02.getExitValue());
System.out.println(" stdout: " + ce_02.getStdout());
System.out.println(" stderr: " + ce_02.getStderr());
System.out.println("CommandExecutor.main Testing End");
}
/*
* The command to execute
*/
protected String command;
/*
* The environment to execute the command with
*/
protected String[] env;
/*
* The directory to execute the command in
*/
protected File dir;
/*
* Flag set when the command has been executed
*/
protected boolean executed = false;
/*
* Exit value from the OS
*/
protected int exitValue;
/*
* Handle to the spawned OS process
*/
protected Process process;
/*
* Std error
*/
protected List<String> stderr;
/*
* Worker Thread to empty the stderr buffer
*/
protected Thread stderrReader;
/*
* Std output
*/
protected List<String> stdout;
/*
* Worker Thread to empty the stdout buffer
*/
protected Thread stdoutReader;
/**
* Creates a new instance of the CommandExecutor initialized to execute the
* specified command in a separate process with the specified environment
* and working directory.
*
* #param env
*/
public CommandExecutor(String command, String[] env, File dir) {
this.command = command;
this.env = env;
this.dir = dir;
}
/**
* Creates a reader thread for the stderr
*/
protected void connectStderrReader() {
stderr = new ArrayList<String>();
final InputStream stream = process.getErrorStream();
final BufferedReader reader =
new BufferedReader(new InputStreamReader(stream));
stderrReader = new Thread(new Runnable() {
public void run() {
String nextLine = null;
try {
while ((nextLine = reader.readLine()) != null) {
stderr.add(nextLine);
}
} catch (IOException e) {
System.out.println(
"CommandExecutor.connectStderrReader() error in reader thread");
e.printStackTrace(System.out);
}
}
});
stderrReader.start();
}
/**
* Creates a reader thread for the stdout
*/
protected void connectStdoutReader() {
stdout = new ArrayList<String>();
final InputStream stream = process.getInputStream();
final BufferedReader reader =
new BufferedReader(new InputStreamReader(stream));
stdoutReader = new Thread(new Runnable() {
public void run() {
String nextLine = null;
try {
while ((nextLine = reader.readLine()) != null) {
stdout.add(nextLine);
}
} catch (IOException e) {
System.out.println(
"CommandExecutor.connectStdoutReader() error in reader thread");
e.printStackTrace(System.out);
}
}
});
stdoutReader.start();
}
/**
* Creates the process for the command
*/
protected void createProcess() {
try {
process = Runtime.getRuntime().exec(command, env, dir);
} catch (IOException e) {
System.out.println("CommandExecutor.exec() error in process creation. Exception: " + e);
e.printStackTrace(System.out);
}
}
/**
* Executes command in a separate process in the specified directory. Method will block until
* the process has terminated. Command will only be executed once.
*/
public synchronized void exec() {
// Future enhancement: check for interrupts to make the blocking nature interruptible.
if (!executed) {
createProcess();
connectStdoutReader();
connectStderrReader();
waitForProcess();
joinThreads();
exitValue = process.exitValue();
executed = true;
}
}
/**
* #return the command
*/
public String getCommand() {
return command;
}
/**
* #return the dir
*/
public File getDir() {
return dir;
}
/**
* #return the env
*/
public String[] getEnv() {
return env;
}
/**
* #return the exitValue
*/
public int getExitValue() {
return exitValue;
}
/**
* #return the stderr
*/
public List<String> getStderr() {
return stderr;
}
/**
* #return the stdout
*/
public List<String> getStdout() {
return stdout;
}
/**
* #return the executed
*/
public boolean isExecuted() {
return executed;
}
/**
* Joins on the 2 Reader Thread to empty the buffers
*/
protected void joinThreads() {
try {
stderrReader.join();
stdoutReader.join();
} catch (InterruptedException e) {
System.out.println("CommandExecutor.joinThreads() error. Exception: ");
e.printStackTrace(System.out);
}
}
/**
* Creates a String representing the state of the object
*/
#Override
public synchronized String toString() {
StringBuilder result = new StringBuilder();
result.append("CommandExecutor:");
result.append(" command: " + command);
result.append(" env: " + Arrays.deepToString(env));
result.append(" dir: " + dir);
result.append(" executed: " + executed);
result.append(" exitValue: " + exitValue);
result.append(" stdout: " + stdout);
result.append(" stderr: " + stderr);
return result.toString();
}
/**
* Waits for the process to terminate
*/
protected void waitForProcess() {
int numberOfRuns = 0;
boolean terminated = false;
while ((!terminated) && (numberOfRuns < NUMBER_OF_RUNS)) {
try {
process.waitFor();
terminated = true;
} catch (InterruptedException e) {
System.out.println("CommandExecutor.waitForProcess() error");
e.printStackTrace(System.out);
numberOfRuns++;
}
}
}
}
Additonal to laalto's comment:
Runntime provides several signatures of exec().
rt.exec("cmd /c c:/tes1.bat "+comd);
rt.exec(new String[] {"cmd","/c","c:/tes1.bat",comd});

Categories