Java Threads - Getting ServerSocket input to update Swing - java

I first asked this question, which I figured out how the EDT works and started reading more on swing and worker threads by reading this. I started to get an understanding of how they work and got my code fixed to where it would run. Now I'm trying to get the information from my worker thread (the server) to update my GUI. I run into a problem though I can't seem to work my way around. The problem is I need to keep listening for new client (As the server is suppose to handle multiple clients) but because that is in a while loop I never hit the return of my worker thread. I can't see any other way to set it up either. Could someone take a look at my code and suggest a way I might be able to get this to work?
Main.class
package com.sever.core;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class Main {
private SocketManager network;
private Window window;
public static void main(String[] args){
Main main = new Main();
main.runGUI();
main.runServer();
}
private void runGUI(){
//Runs the swing components in the EDT.
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
window = new Window();
window.setVisible(true);
}
});
}
private void runServer(){
//Runs the Server process on a worker thread.
SwingWorker<String, String> server = new SwingWorker(){
#Override
protected Object doInBackground() throws Exception {
network = new SocketManager(25595);
/*
* Here is the problem. I need to keep running this code so,
* that I can let multiple clients connect. However,
* it then never reaches the return.
*/
while(true){
try {
network.setSocket(network.getServerSocket().accept());
addUser(network.getSocket());
} catch (Exception e) {
System.out.println("Failed to connect.");
}
}
return network.getMessage();
}
#Override
protected void done(){
try {
window.updateChat(get().toString());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
server.run();
}
private void addUser(Socket s){
try {
Scanner input = new Scanner(s.getInputStream());
network.addUser(input.nextLine());
} catch (Exception e) {
}
}
}

From Java Tutorials
Server
public class Server {
public static void main(String[] args) {
ServerSocket server = new ServerSocket(4444);
while(true) {
new ServerThread(server.accept()).start();
}
}
}
Server Thread
public class ServerThread implements Runnable {
private InputStream in;
private OutputStream out;
public ServerThread(Socket client) {
in = client.getInputStream();
out = client.getOutputStream();
}
public void run() {
// do your socket things
}
}

Related

Java multithreaded server - High CPU Utilization and java.net.SocketException: socket closed [duplicate]

This question already has an answer here:
java.net.SocketException: socket closed TCP Client Server Communication [duplicate]
(1 answer)
Closed 5 years ago.
This is the first java socket/multithreaded application that I write, therefore I would like to apologize for the atrocious code that you are about to witness.
Anyway, most of you will probably regard this code as being basic, a standard server that allows connection from more clients at a time. Also, the server has an interface with just a StopServer button, which closes the server, meanwhile the Client doesn't do anything else than just connect to the server and then disconnect afterwards.
Now, if I simply run the server class, it's ok, nothing 'bad' happens and when I close it, it closes fine, however:
1: If I run the server class, and then I run the client class once, let the client disconnect, and then try to close the server, I get the error:
java.net.SocketException: socket closed
2: Each client will add about ~30-35% of CPU utilization in just a brief run, and that utilization will remain at the "Java(TM) Platform SE Binary" process, for as long as the server continues to run. If I let a client be connected to the server for, let's say 30 seconds, the CPU utilization will reach 100%.
Also, I did a little research and I know that the "socket closed exception" means that you closed the socket, and then continued to try to use it, and also there's probably something wrong with how the server handles the disconnected clients.
Here's the code:
Server
import java.sql.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Server extends JFrame
{ private Connection con;
private static int port = 44444;
private boolean serverKeepGoing;
private static int uniqueId;
private ArrayList<ClientThread> al;
private ServerSocket serverSocket;
public Scanner keyboard = new Scanner(System.in);
public static void main(String[] args) throws IOException
{ Server server = new Server(port);
server.start();
}
public void ServerClose()
{
serverKeepGoing = false;
try
{
for(int i = 0; i < al.size(); ++i)
{ ClientThread tc = al.get(i);
try
{
tc.in.close();
tc.out.close();
tc.socket.close(); }
catch(IOException e) { e.printStackTrace(); }
serverSocket.close();}
}catch(Exception e) { e.printStackTrace(); }
}
public Server (int port)
{
serverInterface();
al = new ArrayList<ClientThread>();
}
public void start()
{ serverKeepGoing = true;
try
{ serverSocket = new ServerSocket(port);
System.out.println("Server is running!");
while(serverKeepGoing)
{ Socket socket = serverSocket.accept(); // accept connection. LINE 65
// ^ALSO :java.net.SocketException: socket closed
// if I was asked to stop
if(!serverKeepGoing)
{ ServerClose(); break;}
ClientThread t = new ClientThread(socket); // make a thread of it
al.add(t); // save it in the ArrayList
t.start();
}
ServerClose(); // means the server has got to be closed
}catch (IOException e) { e.printStackTrace(); System.out.println("Error in method start"); }
}
public synchronized void remove(int id) {
// scan the array list until we found the Id
for(int i = 0; i < al.size(); ++i) {
ClientThread ct = al.get(i);
// found it
if(ct.id == id) {
al.remove(i);
return;
}
}
}
class ClientThread extends Thread
{ // the socket where to listen/talk
Socket socket;
BufferedReader in;
PrintWriter out;
boolean clientKeepGoing;
// my unique id (easier for deconnection)
int id;
public ClientThread(Socket socket)
{ id = ++uniqueId;
this.socket = socket;
try
{
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
}
catch (IOException e) { return; }
}
public void run()
{
boolean clientKeepGoing = true;
while(clientKeepGoing)
{ try
{
}catch(Exception e){ e.printStackTrace(); }
}
// remove myself from the arrayList containing the list of the
// connected Clients
remove(id);
close();
}
// try to close everything
private void close()
{ clientKeepGoing = false;
try {
if(out != null) out.close();
}
catch(Exception e) {}
try {
if(in != null) in.close();
}
catch(Exception e) {};
try {
if(socket != null) socket.close();
}
catch (Exception e) {}
}
}
public void serverInterface(){
JFrame frame = new JFrame("Server");
frame.setLayout(null);
int windowWidth = 300;
int windowHeight = 400;
frame.setBounds(250, 150, windowWidth, windowHeight);
JButton stopServer = new JButton("Stop server");
stopServer.setFocusable(false);
stopServer.setBounds(60, 275, 175, 20);
frame.add(stopServer);
stopServer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
ServerClose();
System.exit(1);
}
});
frame.setResizable(false);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void windowClosing(WindowEvent e)
{ ServerClose();
System.exit(1);
}
public void windowClosed(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
}
The 'java.net.SocketException: socket closed' is on line 65 of the code above.
Client
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
public class Client
{ private BufferedReader in;
private PrintWriter out;
private Socket socket;
private int port;
private String server;
public static void main(String[] args)
{ int portNumber = 44444;
String serverAddress = "localhost";
Client client = new Client(serverAddress, portNumber);
if(!client.start())
return;
}
public Client(String server, int port)
{ this.server = server;
this.port = port;
}
public boolean start()
{ // try to connect to the server
try {
socket = new Socket(server, port);
}
// if it failed not much I can do
catch(Exception ec) {
System.out.println("Error connectiong to server:" + ec);
ec.printStackTrace();
return false;
}
try
{
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);;
}
catch (IOException eIO) {
System.out.println("Exception creating new Input/output Streams: " + eIO);
eIO.printStackTrace();
return false;
}
// creates the Thread to listen from the server
new ListenFromServer().start();
// success we inform the caller that it worked
return true;
}
class ListenFromServer extends Thread
{
public void run()
{ while(true)
{
disconnect() ;
break;
}
}
}
public void disconnect()
{ try {
if(in != null) in.close();
}
catch(Exception e) {} // not much else I can do
try {
if(out != null) out.close();
}
catch(Exception e) {} // not much else I can do
try{
if(socket != null) socket.close();
}
catch(Exception e) {} // not much else I can do
}
}
Note that this is just a fragment of the whole application that I am currently building, I tried to post only what had to do with the Server-Client communication, so I deleted everything else, I'm saying this in case you see something that maybe doesn't have any purpose, I probably omitted to delete it
I see that the question got marked as duplicate, which I consider to be unfair. Firstly, in the 'similar' question, the problem was obvious, the outpot stream was closed, which closed the socket, but the socket had still been used, meanwhile, my program closes everything alltoghether and also has the CPU problem I mentioned, for which I cannnot get any answer from the so called 'similar' question.
The high CPU utilization is because your client threads aren't doing anything else besides burning the CPU with their empty loops. As for the SocketException, it works as planned, so catch it and handle it.

Prevent launching multiple instances of a java application by binding a ServerSocket

I'm trying to prevent the launching multiple instances of a java application by binding a ServerSocket.
Currently I'm executing it in my main as seen below:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(65535, 10);
showFrame();
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
}
It isn't working as in Eclipse I can still open two instances of the application.
There are some crons of using network socket.
What if the socket is used by other apps?
What if there is warning from firewall, which comes with some anti-virus?
Using an exclusive locked file seems to be more reliable.
AppLock.java
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
// http://jimlife.wordpress.com/2008/07/21/java-application-make-sure-only-singleone-instance-running-with-file-lock-ampampampampamp-shutdownhook/
public class AppLock {
private static File f;
private static FileChannel channel;
private static FileLock lock;
public static boolean lock() {
try {
String directory = Utils.getUserDataDirectory();
String fileName = "jstock.lock";
Utils.createCompleteDirectoryHierarchyIfDoesNotExist(directory);
f = new File(directory + fileName);
// Do we need these code?
//if (f.exists()) {
// f.delete();
//}
channel = new RandomAccessFile(f, "rw").getChannel();
lock = channel.tryLock();
if(lock == null) {
channel.close();
return false;
}
} catch (FileNotFoundException ex) {
log.error(null, ex);
} catch (IOException ex) {
log.error(null, ex);
}
return true;
}
public static void unlock() {
// release and delete file lock
try {
if (lock != null) {
lock.release();
channel.close();
f.delete();
}
} catch(IOException e) {
log.error(null, e);
}
}
private static final Log log = LogFactory.getLog(AppLock.class);
}
An usage example
public static void main(String args[]) {
if (false == AppLock.lock()) {
System.exit(0);
}
installShutdownHook();
...
}
private static void installShutdownHook() {
Runnable runner = new Runnable() {
#Override
public void run() {
AppLock.unlock();
}
};
Runtime.getRuntime().addShutdownHook(new Thread(runner, "Window Prefs Hook"));
}
Note, I pick the code snippet from an open source project : AppLock.java
Enforce one instance of a program running with a ServerSocket Lock
Java Code. Put this into a file called Main.java:
import java.net.*;
import java.io.*;
public class Main{
public static void main(String args[]){
ServerSocket socket = null;
try {
socket = new ServerSocket(34567);
System.out.println("Doing hard work for 100 seconds");
try{ Thread.sleep(100000); } catch(Exception e){ }
socket.close();
}
catch (IOException ex) {
System.out.println("App already running, exiting...");
}
finally {
if (socket != null)
try{ socket.close(); } catch(Exception e){}
}
}
}
Compile and run it
javac Main.java
java Main
Test it in a normal case:
Run the program. You have 100 seconds to run the program again in another terminal, it will fall through saying its already running. Then wait 100 seconds, it should allow you to run it in the 2nd terminal.
Test it after force halting the program with a kill -9
Start the program in terminal 1.
kill -9 that process from another terminal within 100 seconds.
Run the program again, it is allowed to run.
Conclusion:
The socket occupation is cleaned up by the operating system when your program is no longer operating. So you can be sure that the program will not run twice.
Drawbacks
If some sneaky person, or some naughty process were to bind all of the ports, or just your port, then your program will not run because it thinks its already running.

How to create a java application which can be run as window service?

I need your advice on creating a Java application which can be used to run as a service. I am using Java service wrapper to install and run it as a service in windows.
I have 2 classes ServiceApp.java & RMIService.java. ServiceApp has main method and RMIService will be a server running to accept connection from client..
Now here is my problem. From my main method, as soon as I create RMIService, the main thread will exit and application halts which is correct. Since I wanted to block the main thread to run it as a service, I created a SocketServer and Socket object and called Socket.accept(). This works fine and service is running as main thread gets blocked but I am not convinced that this is the correct approach. Please provide me the right way to do this . Here is a code snippet :
public class ServiceApp {
public static void main(String[] args) {
System.out.println("Starting RMI server");
{
RMIService rmiService;
try {
rmiService = new RemoteServerService();
Registry registry = LocateRegistry.createRegistry(1099);
registry.rebind("RMIServer", rmiService);
System.out.println("RMI server running");
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ServerSocket serverSocket = null;
Socket socket = null;
try {
serverSocket = new ServerSocket( 7000 );
while ( true )
{
socket = serverSocket.accept(); //This will block the main thread
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
if (socket != null)
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
PS : I had searched Stackoverflow on these questions but couldn't find any that matched with my requirement.
When you export any remote object, including the Registry, one or more non-daemon listener threads are created to listen to the port(s) concerned. These will prevent the process from exiting. You don't need to do anything further, and you certainly don't need an otherwise pointless ServerSocket.
However you do need to prevent the exported remote objects from being garbage-collected, which will unexport them. You need to keep static references to both the Registry and your own remote object(s).
Here is the modified code to make it working. Thanks to EJP for the solution.
ServiceApp.java
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class ServiceApp {
public static RMIService rmiService;
public static Registry registry;
public static void main(String[] args) {
System.out.println("Starting RMI server");
{
try {
rmiService = new RMIService();
registry = LocateRegistry.createRegistry(1099);
registry.rebind("RMIServer", rmiService);
System.out.println("RMI server running");
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
RMIService.java
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class RMIService extends UnicastRemoteObject implements IRemoteServerService
{
private static final long serialVersionUID = 1L;
public RMIService() throws RemoteException {
super();
// Install a security manager.
System.setSecurityManager(new RMISecurityManager());
}
public String pingTest()
{
return "Server says hi";
}
#Override
public boolean resetService() throws RemoteException {
// TODO Auto-generated method stub
return false;
}
}
IRemoteServerService
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IRemoteServerService extends Remote {
boolean resetService() throws RemoteException;
String pingTest() throws RemoteException;
}
Correct me if i'm wrong, but when you bind RMIService to the registry you don't need to block main as the rmiservice gets daemonized. So you just don't need to block the main thread.

Java Networking - Client / Server

My final project for a class is to put together a game, including multiplayer. So I started trying to figure out java networking, and I'm kind of stuck.
Each of the two game clients needs to be able to send and receive messages to and from the other client.
The way I figured I would handle this is that I have a NetworkServer and NetworkClient objects that runs in their own threads.
I was thinking that I would just start them from my main game application, but I wanted to do some testing first, so I set this project up:
NetworkClient:
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
public class NetworkClient extends Thread {
Socket server;
ObjectOutputStream out;
Timer timer;
public NetworkClient(String hostname, int port) throws IOException
{
server = new Socket(hostname, port);
out = new ObjectOutputStream(server.getOutputStream());
timer = new Timer();
timer.schedule(new SendTask(), 0, 1*1000);
}
public void sendData(Integer b) throws IOException {
out.writeObject(b);
}
class SendTask extends TimerTask {
Integer i = new Integer(1);
public void run() {
System.out.println("Client: Sending Integer: " + i.toString());
try {
sendData(i);
i = new Integer(i.intValue()+1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // run()
} // class SendTask
}
NetworkServer:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class NetworkServer extends Thread {
private ServerSocket serverSocket;
private Socket client;
private Integer i;
private ObjectInputStream in;
public NetworkServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
//serverSocket.setSoTimeout(10000);
}
public void run()
{
try {
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
client = serverSocket.accept();
System.out.println("Just connected to " + client.getRemoteSocketAddress());
in = new ObjectInputStream(client.getInputStream());
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
while(true)
{
try
{
i = (Integer) in.readObject();
System.out.println("Server: Received the integer: " + i.toString());
}
catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}
catch(IOException e)
{
e.printStackTrace();
try { client.close();} catch (IOException e1) {}
break;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Network (The thing I'm using to try and test this):
import java.io.IOException;
public class Network {
NetworkClient client;
NetworkServer server;
public Network() throws IOException {
server = new NetworkServer(6066);
server.start();
client = new NetworkClient("192.168.1.196", 6066);
client.start();
}
public static void main(String [] args)
{
try
{
Network n = new Network();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
I have the timer in there to facilitate sending data from the client to the server, which would normally be done by my game, but since I'm testing I had to have it send somehow.
When I run this where the client and server are talking to each other, I get both the Sent and Received messages.
When I put it on my laptop (and change the IP in NetworkClient to match my desktop, and vice versa on my desktop) and run it in both places, the client on the desktop sends to the server on the laptop, but the client on the laptop does not send to the server on the desktop.
And at some point during the running, I get an exception about that client's connection being reset by peer, though the working client/server connection continue.
So, I guess my question is, Does anyone know why it works in one direction but not bidirectionally?
FIXED!!
Edit: Gah, I figured it out. It had to do with the timing on starting the two servers.
I changed Network to:
import java.io.IOException;
public class Network {
NetworkClient client;
NetworkServer server;
public Network() throws IOException {
startServer();
startClient();
}
private void startServer() throws IOException {
server = new NetworkServer(6066);
server.start();
}
private void startClient(){
boolean isConnected = false;
while (!isConnected) {
try {
client = new NetworkClient("192.168.1.196", 6066);
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
continue;
}
isConnected = true;
}
client.start();
}
public static void main(String [] args)
{
try
{
Network n = new Network();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
Edit your Firewall. Make sure that java.exe has inbound and outbound traffic enabled. Also, add a rule to your Firewall for port 6066.

Infinite loop when deploying OSGI bundle with network server

I'm trying to implement OSGI bundle with network server which uses network sockets.
This is the complete source code: http://www.2shared.com/file/RMXby331/CB_27.html
This is the Activator:
package org.DX_57.osgi.CB_27.impl;
import java.util.Properties;
import org.DX_57.osgi.CB_27.api.CBridge;
import org.DX_57.osgi.CB_27.impl.EchoServer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
public class CBridgeApp implements BundleActivator {
public void start(BundleContext bc) throws Exception {
ServiceRegistration registerService = bc.registerService(CBridge.class.getName(), new CBridgeImpl(), new Properties());
EchoServer();
}
public void stop(BundleContext bc) throws Exception {
boolean ungetService = bc.ungetService(bc.getServiceReference(CBridge.class.getName()));
}
private void EchoServer() {
EchoServer method = new EchoServer();
}
}
This is the source code if the Java Network server:
package org.DX_57.osgi.CB_27.impl;
import java.net.*;
import java.io.*;
public class EchoServer
{
ServerSocket m_ServerSocket;
public EchoServer()
{
try
{
// Create the server socket.
m_ServerSocket = new ServerSocket(12111);
}
catch(IOException ioe)
{
System.out.println("Could not create server socket at 12111. Quitting.");
System.exit(-1);
}
System.out.println("Listening for clients on 12111...");
// Successfully created Server Socket. Now wait for connections.
int id = 0;
while(true)
{
try
{
// Accept incoming connections.
Socket clientSocket = m_ServerSocket.accept();
// accept() will block until a client connects to the server.
// If execution reaches this point, then it means that a client
// socket has been accepted.
// For each client, we will start a service thread to
// service the client requests. This is to demonstrate a
// multithreaded server, although not required for such a
// trivial application. Starting a thread also lets our
// EchoServer accept multiple connections simultaneously.
// Start a service thread
ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++);
cliThread.start();
}
catch(IOException ioe)
{
System.out.println("Exception encountered on accept. Ignoring. Stack Trace :");
ioe.printStackTrace();
}
}
}
public static void main (String[] args)
{
new EchoServer();
}
class ClientServiceThread extends Thread
{
Socket m_clientSocket;
int m_clientID = -1;
boolean m_bRunThread = true;
ClientServiceThread(Socket s, int clientID)
{
m_clientSocket = s;
m_clientID = clientID;
}
public void run()
{
// Obtain the input stream and the output stream for the socket
// A good practice is to encapsulate them with a BufferedReader
// and a PrintWriter as shown below.
BufferedReader in = null;
PrintWriter out = null;
// Print out details of this connection
System.out.println("Accepted Client : ID - " + m_clientID + " : Address - " +
m_clientSocket.getInetAddress().getHostName());
try
{
in = new BufferedReader(new InputStreamReader(m_clientSocket.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(m_clientSocket.getOutputStream()));
// At this point, we can read for input and reply with appropriate output.
// Run in a loop until m_bRunThread is set to false
while(m_bRunThread)
{
// read incoming stream
String clientCommand = in.readLine();
System.out.println("Client Says :" + clientCommand);
if(clientCommand.equalsIgnoreCase("quit"))
{
// Special command. Quit this thread
m_bRunThread = false;
System.out.print("Stopping client thread for client : " + m_clientID);
}
else
{
// Echo it back to the client.
out.println(clientCommand);
out.flush();
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
// Clean up
try
{
in.close();
out.close();
m_clientSocket.close();
System.out.println("...Stopped");
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
}
}
}
When I try to deploy the bundle on Glassfish server the application server hangs but I can connect to the java network server using the java client. It seems that there is a infinite loop. I need help to fix the code.
Best wishes
Your bundle activator start method never returns, because you're calling constructor of your service with infinite loop. A good practice is to return as fast as possible from bundle activators.
Here is an idea how to rewrite your code:
public class EchoServer {
private volatile boolean started;
public void start() {
new Thread(new Runnable() {
#Override
public void run() {
started = true;
try {
m_ServerSocket = new ServerSocket(12111);
} catch(IOException ioe) {
System.out.println("Could not create server socket at 12111. Quitting.");
System.exit(-1);
}
System.out.println("Listening for clients on 12111...");
// Successfully created Server Socket. Now wait for connections.
int id = 0;
while (started) {
try {
Socket clientSocket = m_ServerSocket.accept();
ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++);
cliThread.start();
} catch(IOException ioe) {
System.out.println("Exception encountered on accept. Ignoring. Stack Trace :");
ioe.printStackTrace();
}
}
}
}).start();
}
public void stop() {
started = false;
}
}
Activator
public class CBridgeApp implements BundleActivator {
private EchoServer method;
public void start(BundleContext bc) throws Exception {
...
method = new EchoServer();
method.start();
}
public void stop(BundleContext bc) throws Exception {
...
method.stop();
}
}

Categories