Based in a code I saw in Stackoverflow and other pages on Internet, I've created a method to stop and start tomcat at the moment I'll run a process in my system because I need to clean memory in my OS, I use System.gc() but still not enough to free memory, this is the code:
Global declaration:
private String server = "localhost";
Method to stop-start tomcat:
public void tomcat(){
try{
Socket s = new Socket(server,8005);
if(s.isConnected()){
PrintWriter print = new PrintWriter(s.getOutputStream(),true);
print.println("SHUTDOWN"); /*Command to stop tomcat according to the line "<Server port="8005" shutdown="SHUTDOWN">" in catalina_home/conf/server.xml*/
print.close();
s.close();
}
Runtime.getRuntime().exec(System.getProperty("catalina.home")+"\\bin\\startup.bat"); /*Instruction to run tomcat after it gets stopped*/
}catch (Exception ex){
ex.printStackTrace();
}
}
The code line to start tomcat works perfectly, but no the instructions to stop it because, when I instance the socket, gives me the following message: Connection refused: connect.
How can I solve this? or, is there another way to stop tomcat?
Thanks in advance.
public static void shut_server(String lien)
{
try {
Process child = Runtime.getRuntime().exec(lien+"/shutdown.sh");
System.out.println("Serveur est atteins");
} catch (IOException ex) {
Logger.getLogger(Installation.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("erreur de demarrage");
}
}
lien = path to your tomcat bin file
for example - /home/zakaria/Téléchargements/apache-tomcat-8.0.21/bin
I had similar issue. I was getting the "Connection refused: connect" error message on creating the socket.
However, my use case is different from the one posted by Vlad. When the Tomcat server is starting up, my app is checking availability of some resources and if they are not, it needs to shutdown the server.
I added a 30 seconds sleep just before the line creating socket:
try {
Thread.sleep(30000);
}
catch (Exception excp) {}
Socket socket = new Socket("localhost", port);
and it started working.
I think when Tomcat is starting up it needs some time to make the shutdown port ready to work.
The selection of 30 seconds is arbitrary, it could be probably shorter.
FYI, my Tomcat is running as Windows service.
Related
I am writing an application that streams data that clients can then listen to and receive. However I am running into an issue with closing a socket when a client is no longer listening.
What I do is create a ServerSocket, when then waits for a connection and once it is connected, I start streaming the data. However, once the client is no longer connected, I am stuck in a loop of streaming and cannot tell if anyone is listening. Is there a way around this?
try {
serverSocket = new ServerSocket(STREAM_PORT);
Socket clientSocket = serverSocket.accept();
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(), true);
while (true) {
pw.println("some data");
}
} catch (SocketException e) {
// Never occurs when client disconnects
} catch (IOException e) {
// Never occurs when client disconnects
}
I have tried using socket.isClosed(), but it always returns false. Am I approaching this from the wrong angle, or is there a way to do it. I would ideally not want the client to have to send the server a "end" command.
EDIT: Edited to reflect what current code I am running after #Rod_Algonquin suggestion
As you are using PrintWriter, which swallows I/O exceptions, you need to call checkError() after each write to see if an error has occurred.
I use sauronsoftware.ftp4j.FTPClient to do scheduled file downloads from FTP servers.
My problem is that FTP server suddenly dies while the client downloads a file from it.
This is what i do:
for (FTPFile remoteFile : remoteFiles) {
String remoteFileName = remoteFile.getName();
String localPath = ftpDir.getLocalPath() + remoteFileName;
log.debug("Downloading remote file {} to local path {}", remoteFileName, localPath);
try {
client.download(remoteFileName, new File(localPath));
if (!ftpDir.isLeaveFilesOnServer()) {
//Delete remote file
client.deleteFile(remoteFileName);
}
} catch (IllegalStateException e) {
log.error("FTPException ",e);
fcr.addErrorFile(remoteFileName);
} catch (IOException e) {
log.error("FTPException ",e);
The problem is that download(...) runs by separate thread and when FTP server dies this thread continues to run anyway like forever. Is there a way to come around this problem or should i use another FTP client that can handle cases like this?
I'm not sure if your problem is your FTP connection dies sudden and unexpedtecly, or if the problem is the main thread finished its execution before files are downloaded. If we are talking about the second scenario, then maybe you can use this other method of the same FTPClient class:
public void download(java.lang.String remoteFileName,
java.io.File localFile,
FTPDataTransferListener listener)
and then make the main thread to wait until all downloads have finished before ending
I have a list of feeds in a database that I use to download a XML file from a FTP server and then parse it. The scrpt is bundled up into a jar file which is run daily using Windows Task Scheduler. Occasionally the request get haulted at grabbing a certain xml file. So far it has happened about 3 times in 2 weeks with no real pattern that I can see.
When it does mess up, I go to the computer it is being run from, I see the command window open and it is stopped before the xml has been fully downloaded. If I close the command window and run the task manually everything will work fine.
The code that I am using to download the xml file is:
private void loadFTPFile(String host, String username, String password, String filename, String localFilename){
System.out.println(localFilename);
FTPClient client = new FTPClient();
FileOutputStream fos = null;
try {
client.connect(host);
client.login(username, password);
String localFilenameOutput = createFile(assetsPath + localFilename);
fos = new FileOutputStream(localFilenameOutput);
client.retrieveFile(filename, fos);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null)
fos.close();
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This function is being called in a loop and when it fails, everything stops and the script doesn't go onto the next feed.
I'm not sure what is happening, possibly the connection being lost, but I would think that the try/catch would catch if that is happening. I'm not sure if a timeout would do the trick or threads need to be used (but I've never worked with threads)
Could anyone point me in the right direction onto why this is happening and what I can do to fix the problem
UPDATE - Set a timeout for the data connection
Since the last file is only partially downloaded, and given the source of FTPClient.retrieveFile(), I think it may be a problem on the server side (something that make it hang, or even die - who knows). Obviously one can't repair the server or even know what's going on there, anyway I suggest to add a timeout with setDataTimeout(int) and catch the possible SocketTimeoutException separately to be logged in a different place and maybe sent to the FTP server admins (along with the time information when it happened) so they can merge the logs and see what's the issue.
OLD ANSWER
I didn't notice that you connect and login for each and every file, so the following is just an optimization not to close the control connection and succesfully logout, but it should not address the problem.
You could start the JVM in debug mode and attach a debugger when it hangs, anyway according to this answer and this thread it can be a timeout problem on the network equipment devices (routers). From the FTPClient Javadoc
During file transfers, the data connection is busy, but the control
connection is idle. FTP servers know that the control connection is in
use, so won't close it through lack of activity, but it's a lot harder
for network routers to know that the control and data connections are
associated with each other. Some routers may treat the control
connection as idle, and disconnect it if the transfer over the data
connection takes longer than the allowable idle time for the router.
One solution to this is to send a safe command (i.e. NOOP) over the control connection to reset the router's idle timer. This is enabled as follows:
ftpClient.setControlKeepAliveTimeout(300); // set timeout to 5 minutes
Do you check the return status of any of the calls or is that the code?
There is a call completePendingCommand() that has to be used on occassion. That may be something to look into.
Also, you won't see an IO exception, I belive it gets repackaged as a CopyStreamException
You might want to also change the return value to a boolean since you trap the exceptions, at least the calling loop will know whether the tranfer happened or not.
private boolean loadFTPFile(String host, String username, String password, String filename, String localFilename){
System.out.println(localFilename);
FTPClient client = new FTPClient();
FileOutputStream fos = null;
try {
client.connect(host);
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)){
client.disconnect();
System.err.println("FTP server refused connection.");
return false;
}
if (!client.login(username, password)){
client.logout();
return false;
}
String localFilenameOutput = createFile(assetsPath + localFilename);
fos = new FileOutputStream(localFilenameOutput);
boolean result = client.retrieveFile(filename, fos);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
if (result){
System.out.println("\tFile Transfer Completed Successfully at: " + sdf.format(Calendar.getInstance().getTime()));
// ftp.completePendingCommand();
}
else {
System.out.println("\tFile Transfer Failed at: " + sdf.format(Calendar.getInstance().getTime()));
}
return result;
}catch (CopyStreamException cse){
System.err.println("\n\tFile Transfer Failed at: " + sdf.format(Calendar.getInstance().getTime()));
System.err.println("Error Occurred Retrieving File from Remote System, aborting...\n");
cse.printStackTrace(System.err);
System.err.println("\n\nIOException Stack Trace that Caused the Error:\n");
cse.getIOException().printStackTrace(System.err);
return false;
}catch (Exception e){
System.err.println("\tFile Transfer Failed at: " + sdf.format(Calendar.getInstance().getTime()));
System.out.println("Error Occurred Retrieving File from Remote System, aborting...");
e.printStackTrace(System.err);
return false;
} finally {
try {
if (fos != null)
fos.close();
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
It's not a threading issue. Chances are it is caused by something in the loop since that code looks like it should clean up just fine. That said, for testing you will probably want to add
catch (Exception e) {
e.printStackTrace();
}
after the IOException catch clause. It's possible that another exception is being thrown.
Another thing, if you are pulling results from the database result set one at a time and doing the FTP gets, that might be a problem. Unless the results are all brought back by the JDBC call at once, that too could time out. Not all database queries actually return the entire result set to the client at once.
I have a java app that holds open many connections to an address, probably in the ballpark of 2,000 at once, with hardly any activity, mostly open for monitoring purposes passing a few bytes every now and then. When new connections need to be opened up, it automatically opens them and adds them to its pool. Sometimes though, for an unknown reason, the application receives a ClosedByInterruptException immediately during/after creating the socket to the remote address. To the best of my knowledge, this only occurs on the client side as a result of an interrupt signal to the thread. I have checked and rechecked the source code surrounding the problem area and it seems ok. I was hoping I could get someone's expertise as to if there could be an alternate cause, besides source code, for instance, is there a system reason that causes this? Is there a hardware cause? Server level/router level? My network knowledge I would consider amateur, but is 2K connections too many for a router, or no?
INFO [08 Sep 2011 23:11:45,982]: Reconnecting id 20831
ERROR [08 Sep 2011 23:11:45,990]: IOException while creating plain socket channel
java.nio.channels.ClosedByInterruptException
at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:184)
at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:518)
at com.*.createSocketChannelPlain(MyTask.java:441)
at com.*._executeTask(MyTask.java:176)
at com.*.executeTask(MyTask.java:90)
at com.*.ThreadPool$WorkerThread.run(ThreadPool.java:55)
ERROR [08 Sep 2011 23:11:45,990]: Could not open socket
WARN [08 Sep 2011 23:11:45,990]: WorkerThread_24 received interrupted exception in ThreadPool
java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at com.*.TaskQueue.getTask(TaskQueue.java:39)
at com.*.ThreadPool$WorkerThread.run(ThreadPool.java:48)
Update: I would like to try and offer all I can to help others contribute to a diagnosis. So here is the actual function where the exception occurs, only difference being the line marking I added to line 441.
private SocketChannel createSocketChannelPlain() throws TaskFailedException {
SocketChannel socketChannel = null;
try {
// Create a non-blocking socket channel to use to communicate for imap connection
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
try {socketChannel.socket().setSoLinger(true, 0);} catch (Exception e) {}
try {socketChannel.socket().setKeepAlive(true);} catch (Exception e) {}
/*Line 441*/ socketChannel.connect(new InetSocketAddress(_HOSTNAME, _PORT));
//System.out.println("Started connection");
// Complete connection
while (!socketChannel.finishConnect()) {
// do something until connect completed
try {
//do what you want to do before sleeping
Thread.sleep(500);//sleep for 500 ms
//do what you want to do after sleeping
} catch(InterruptedException ie){
//If this thread was interrupted by another thread
try { socketChannel.close(); } catch (Exception e) {}
finally { socketChannel = null; }
break;
}
}
//System.out.println("Finished connecting");
return socketChannel;
} catch (IOException e) {
logger.error("IOException while creating plain socket channel to gmail", e);
try { socketChannel.close(); } catch (Exception e1) {}
finally { socketChannel = null; }
//throw new TaskFailedException("IOException occurred in createSocketChannel");
}
return socketChannel;
}
What OS are you running this on? I don't know about Windows, but on Linux (and presumably other Unix-like OSes), you can run out of file handles by having large numbers of sockets. You can work around this by doing ulimit -n 8192 or similar before running the Java app. Alternatively, edit /etc/security/limits.conf and set nofile. All of that said, ClosedByInterruptedException would be an odd way to notice this.
If the above isn't the issue, the next thing I'd try would be to run tcpdump (if we're talking about a GUI-less machine) or Wireshark (if we aren't) and capture the traffic your program's generating, looking for weird things happening at the time that connection starts.
I'm trying to connect a socket to an non-existent server, and I really don't understand why an exception is not being raised.
Here is my code:
public class TestSocket extends Activity {
private static final String TAG = "TestSocket";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BasicThread t = new BasicThread();
t.start();
}
class BasicThread extends Thread {
#Override
public void run() {
Log.d(TAG, "Before");
try {
new Socket("42.42.42.42", 12345);
Log.d(TAG, "Connected");
} catch (Exception e) {
Log.d(TAG, "Exception");
}
Log.d(TAG, "After");
}
}
}
I also tried with my own IP address while running Wireshark, and I first get [SYN] from Android to my computer and then [RST, ACK] from my computer to Android (because nothing is listening at this port), but I still do not get an exception on Android.
Also I’m testing on a physical phone (Nexus S), and I do have the internet permission in my Manifest.
Why aren't I getting an Exception?
Edit:
More precisely, the output I get is
D/TestSocket(17745): Before
D/TestSocket(17745): Connected
D/TestSocket(17745): After
(and not Exception)
In the Socket constructor, it's thrown when the IP address of the host can't be determined, so I assume that because you aren't passing a hostname which needs resolution, a different exception would be getting thrown instead. I believe the exception actually comes from the URL class or such which does the resolution, and from nowhere else.
The connect(..) method should throw an exception but doesn't appear to, as you say.
Edit: apparently Android (some versions) doesn't work properly here, so it's probably a bug: http://code.google.com/p/android/issues/detail?id=6144. It doesn't look like the link refers to the emulator as I had thought.
There are a variety of things that can cause a socket connect to fail with an exception.
However, if the SYN message that the TCP protocol sends to start the connection process is
blocked by a firewall,
routed through a borked network, or
routed to some endpoint that doesn't respond,
then TCP stack on the initiating machine will just retry, and retry. If you have a connect timeout set, you will eventually get an exception, but it could take a long time.
The fact that it works on the Android emulator and not on the real device simply means that they are implemented or configured differently. (For instance, they may have different default connect timeouts ... of the emulator may be designed to give connection refused in that scenario.)
The bottom line is that you need to make your code work on the real device. Figure out the best way to make your device set a connect timeout, and check that that works when talking to the non-existent server.
Your try catch code doesn't catch IO Exceptions. Try something like this
try
{
// to get the ip address of the server by the name<br>
InetAddress ip =InetAddress.getByName("example.com");
sock= new Socket(ip,Server.PORT);
ps= new PrintStream(sock.getOutputStream());
ps.println(" Hi from client");
DataInputStream is = new
DataInputStream(sock.getInputStream());
System.out.println(is.readLine());
}catch(SocketException e){
System.out.println("SocketException " + e);
}catch(IOException e){
System.out.println("IOException " + e);
}