Using addShutdownHook in java - java

I want to do following operation in ordered wise
1. Stop jetty server
2. Delete used resource from jetty
3. Restart jetty server.
I have done this above using shutdownhook in java as below :
<code>
Thread restartThread = new Thread(){
public void run(){
try {
sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String osName = System.getProperty("os.name");
logger.debug("OS name:" + osName);
if (osName != null
&& osName.toUpperCase().startsWith("WINDOWS")) {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
List<String> cmdLine = new ArrayList<String>();
cmdLine.add("cmd.exe");
cmdLine.add("/C");
cmdLine.add("start");
cmdLine.add("\"\"");
cmdLine.add(getBaseDir() + File.separator + "restart.bat");
final ProcessBuilder pb = new ProcessBuilder(cmdLine);
Process process = pb.start();
if (process.exitValue() == 0) {
// after stopping server delete stores
deleteCertificates();
// restores files
restoreFiles(tmpdir, backupfilelist);
}
//p.waitFor();
} catch (IOException e) {
logger.error("Failed to restart:" + e.getMessage(), e);
}
}
});
System.exit(0);
} else {
try {
Runtime.getRuntime().exec("service appservice restart");
} catch (IOException e) {
logger.error("Failed to restart:" + e.getMessage(), e);
}
}
}
};
restartThread.start();
<code>
my concern is will it do it sequentially execution, otherwise application will fail to restore.

Related

FTPClient connection with Java on AWS Virtual Machine

I'm trying to connect to my FTP server in Java SE 1.8. To do so I use this method :
private void connectFTP() {
String server = "ftp.XXXXXXXXXX.site";
int port = 21;
String user = "XXXX";
String pass = "XXXX";
if(!ftpConnexionSuccess.get())
{
client = new FTPClient();
client.configure(new FTPClientConfig(FTPClientConfig.SYST_UNIX));
try {
client.connect(server, port);
ftpConnexionSuccess.set(client.login(user, pass));
if (!ftpConnexionSuccess.get()) {
System.out.println("Could not login to the server");
return;
}
else
{
System.out.println("LOGGED IN SERVER");
client.changeWorkingDirectory("/crypto");
listenedFile = getListenedFile();
System.out.println(listenedFile.getName());
if(listenedFile != null)
{
baseFileTimeStamp.set(listenedFile.getTimestamp().getTimeInMillis());
}
System.out.println(baseFileTimeStamp);
}
} catch (Exception ex) {
System.err.println("FTP connection error : Sleeping for 5 seconds before trying again (" + ex.getMessage() + ")");
ex.printStackTrace();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {e.printStackTrace();}
try {
client.disconnect();
} catch (IOException e) {e.printStackTrace();}
connectFTP();
}
}
}
It works great when I'm on Eclipse and when I export the app on my Windows 10.
Nonetheless, when I try to launch the app on my AWS Webmachine I get a null pointer exception at "listenedFile". The method to listen to this file is the one below.
private FTPFile getListenedFile() {
FTPFile returnedFile = null;
try {
for(FTPFile file : client.listFiles())
{
if(file.getName().contains("filetolisten.txt"))
returnedFile = file;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
try {
client.disconnect();
} catch (IOException e1) {e1.printStackTrace();}
connectFTP();
return getListenedFile();
}
return returnedFile;
}
I thought it was because of the line
client.configure(new FTPClientConfig(FTPClientConfig.SYST_UNIX));
I tried to delete the line, and to replace SYST_UNIX with SYST_NT, but nothing worked.
I tried to delete the line, and to replace SYST_UNIX with SYST_NT, but nothing worked. Also updated Java, updated the common-nets library. Nothing worked

How can i stop the groupMonitor.run method from crashing my ScheduledExecutorService?

groupMonitor.run("", "") is listening via IP Network to some electrical components.
The problem: is that all 5-6 hours groupMonitor.run("", "") crashes and needs to be called again. Quickly said: groupMonitor.run("", "") has to listen all the time via IP Network.
Another problem is: when groupMonitor.run("", "") crashes it prints all 100ms "redo groupMonitor ..." and is spaming my network so heavily that my IP Gateway (which accepts the connections) gets stuck and refuses all future incoming requests
This is the minimied main so to say
GroupMonitorOrig groupMonitor = new GroupMonitorOrig();
//when new groupMonitor is created the boolean MonitorExited is initialized with true
while (true) {
if (groupMonitor.monitorExited) { //this part gets executed when groupMonitor.run("", "") method has "crashed"
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
System.out.println("redo groupMonitor ... ");
groupMonitor.run("192.168.1.7", 2169);
} catch (Exception ex) {
}
}
};
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, 0, 100, TimeUnit.MILLISECONDS);
}
try {
TimeUnit.SECONDS.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
This is groupmonitor's run function
public void run(String remoteHost, int port) {
final InetSocketAddress remote = new InetSocketAddress(remoteHost, port);
try (KNXNetworkLink knxLink = KNXNetworkLinkIP.newTunnelingLink(null, remote, false, TPSettings.TP1);
ProcessCommunicator pc = new ProcessCommunicatorImpl(knxLink)) {
// start listening to group notifications using a process listener
pc.addProcessListener(this);
System.out.println("Monitoring network using net/IP server " + remoteHost + " ...");
while (knxLink.isOpen()) {
Thread.sleep(1000);
}
monitorExited = false;
pc.detach();
} catch (final KNXException | InterruptedException | RuntimeException e) {
System.err.println(e);
monitorExited = true;
}
}
I can't test run but can you try below -
The while(true) can be avoided
GroupMonitorOrig groupMonitor = new GroupMonitorOrig();
//when new groupMonitor is created the boolean MonitorExited is initialized with true
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
if (groupMonitor.monitorExited) {
System.out.println("starting new groupMonitor ... ");
groupMonitor.run("192.168.1.7", 2169);
}
} catch (Exception ex) {
System.err.println("Error in Runnable - " + ex.getMessage());
}
}
};
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, 0, 100, TimeUnit.MILLISECONDS);
public void run(String remoteHost, int port) {
monitorExited = false;
final InetSocketAddress remote = new InetSocketAddress(remoteHost, port);
KNXNetworkLink knxLink = null;
ProcessCommunicator pc = null;
try {
knxLink = KNXNetworkLinkIP.newTunnelingLink(null, remote, false, TPSettings.TP1);
pc = new ProcessCommunicatorImpl(knxLink);
pc.addProcessListener(this);
System.out.println("Monitoring network using net/IP server " + remoteHost + " ...");
while (knxLink.isOpen()) {
Thread.sleep(1000);
}
safeDetach(pc);
safeClose(knxLink);
} catch (final KNXException | InterruptedException | RuntimeException e) {
System.err.println("Error in checking liveliness - " + e.getMessage());
safeDetach(pc);
safeClose(knxLink);
}
monitorExited = true;
}
private void safeDetach(ProcessCommunicator pc) {
try {
if (pc != null) pc.detach();
} catch (Exception e) {
System.err.println("Could not safely detach pc - " + e.getMessage());
}
}
private void safeClose(KNXNetworkLink knxLink) {
try {
if (knxLink != null) knxLink.close();
} catch (Exception e) {
System.err.println("Could not safely close link - " + e.getMessage());
}
}

Logging into a text file in Android

I need to log my messages not only into system logs ( as I know, system log buffer is quite short, but I need to see logs for 3-5 days ), but also in a separate text file. Logging must be asynchronous.
Could you give me an advice about which component should I use in this case?
Thanks.
I hope it will be useful for you.
public void appendLog(String text) {
File logFile = new File("sdcard/log.file");
if (!logFile.exists()) {
try {
logFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Don't forget to add permission for android.permission.WRITE_EXTERNAL_STORAGE in Manifest!
Works asynchronously and dose not need to permission !
just remember call the init method from your application in onCreateMethod for initializing the Logger
class Logger {
private static File logFileLoc;
private static ExecutorService logExecutor;
public static void init(Context applicationContext, String logFileName, boolean reCreate) {
logFileLoc = new File(applicationContext.getCacheDir(), logFileName);
if (reCreate && logFileLoc.exists()) logFileLoc.delete();
logExecutor = Executors.newSingleThreadExecutor();
}
public static void log(final String tag, final String msg) {
if (logFileLoc == null) try {
throw new Exception("First you should call init method in your application");
} catch (Exception e) {
e.printStackTrace();
}
Log.d(tag, msg);
logExecutor.execute(new Runnable() {
#Override
public void run() {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(logFileLoc,true));
String timeStamp = DateFormat.getDateTimeInstance().format(new Date(System.currentTimeMillis()));
writer.append(timeStamp + " " + tag + " : " + msg );
writer.newLine();
writer.flush();
writer.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
also you can do the same thing with Timber library for more info :
https://medium.com/#vicky7230/file-logging-with-timber-4e63a1b86a66

Notify client in client server application

first of all, I'm rather new to socket programming to go easy on me ;).
I have a Java program that uses client-server programming to communicate between 1 or more clients and the server. So the clients can send any number of messages to the server where the messages are dealt with and all is fine so far. Now I want to notify the clients of e.g. database changes on the server side. So for example if one client changes for example table A, the other clients should also be notified about this change.
What I have so far is the following (server):
ExecutorService executor = null;
try (ServerSocket socket = new ServerSocket(port);)
{
executor = Executors.newFixedThreadPool(getThreadCount(5));
while(true)
{
Socket clientSocket = socket.accept();
Runnable worker = new PCRequestMapper(clientSocket);
executor.execute(worker);
}
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
finally
{
if(executor != null)
{
executor.shutdown();
}
}
The request mapper class then looks like this:
public class PCRequestMapper implements Runnable
{
private Socket client = null;
private static Map<Integer, PCRequestData> requestData = null;
public PCRequestMapper(Socket client)
{
this.client = client;
}
#Override
public void run()
{
try (ObjectInputStream in = new ObjectInputStream(
client.getInputStream());
ObjectOutputStream writer = new ObjectOutputStream(
client.getOutputStream());)
{
System.out.println("Thread started in PCRequestHandler with name: "
+ Thread.currentThread().getName());
Object recObj = in.readObject();
// ToDo Do something
PCBaseRequest req = (PCBaseRequest) recObj;
System.out.println("Req type: " + req.getRequestType() + " name: "
+ req.getName());
PCRequestData data = requestData.get(req.getRequestType());
if(data == null)
{
PCException ex = new PCException();
ex.setStackTrace(new Throwable().getStackTrace());
PCBaseReply reply = getErrorReply("No mapped request handler found in services.xml for request: "+req.getRequestType()+" - "+req.getName(),
PCException.NO_MAPPED_HANDLER, ex);
writer.writeObject(reply);
}
else
{
Class<?> c = Class.forName(data.getMappedClass());
Constructor<?> cons = c.getConstructor();
PCIRequestHandler object = (PCIRequestHandler)cons.newInstance();
PCBaseReply reply = object.heyHo(req);
System.out.println("Writing reply: "+reply.getClass());
writer.writeObject(reply);
}
} catch (IOException ioe)
{
ioe.printStackTrace();
} catch (ClassNotFoundException cnfe)
{
cnfe.printStackTrace();
} catch (NoSuchMethodException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
It basically takes a message (request), maps it to a configured class and then that class performs whatever action needed.
On the client side, I have a class called RequestSender, which is used to send arbitrary requests to the server:
public class PCRequestSender
{
private static int getPort(int defaultPort)
{
final String port = PCConfigHandler.getStringProperty("serverPort");
if (null != port)
{
try
{
return Integer.parseInt(port);
} catch (NumberFormatException e)
{
System.out.println("Value of port property"
+ " is not a valid positive integer [" + port + "]."
+ " Reverting to default [" + defaultPort + "].");
}
}
return defaultPort;
}
public static PCBaseReply sendRequest(PCBaseRequest req)
{
PCBaseReply reply = null;
int port = getPort(8081);
String address = PCConfigHandler.getStringProperty("serverAddress");
try (Socket serverSocket = new Socket(address, port);
ObjectOutputStream out = new ObjectOutputStream(
serverSocket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(
serverSocket.getInputStream());)
{
out.writeObject(req);
Object recObj = in.readObject();
reply = (PCBaseReply) recObj;
System.out.println("Reply: "+reply);
} catch (IOException e)
{
e.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
return reply;
}
}
Now I'm a bit at a loss, because I would also like to constantly listen to a server socket to catch notifications. Do I need another socket on the server side? Is my setup not tooooo ideal?
I'm helpful for any hints...thanks!

Apache Commons Net FTPClient abort file store

I'm developing an applet to allow FTP upload from a webapp...
The send operation is working fine, but I'd like to able to cancel a file storing in progress.
I'm not very fluent with threads. My first attempt was to call ftp.abort() in the cancel thread, but the abort method was only called when the storeFile method finished, like if the send thread was locking the ftp object.
So I changed the code to interrupt the send thread and check it in the copy stream listener. The file storing stops as expected, but ftp.abort() call hangs the application, it never complete.
Any ideas?
Thanks,
Philip
Send operation:
botaoEnviar.setEnabled(false);
botaoCancelar.setEnabled(true);
textField.requestFocus();
threadEnvio = new Thread(new Runnable()
{
#Override
public void run()
{
FileInputStream fis = null;
try
{
if(arquivoSelecionado == null)
{
throw new IllegalArgumentException("Arquivo deve ser informado");
}
try
{
ftp = new FTPClient();
ftp.connect("192.168.1.243");
}
catch(Exception e)
{
throw new FtpConnectionException("Não foi possível conectar no servidor FTP", e);
}
if(!ftp.login("c001", "0AJF2J36"))
{
throw new IllegalArgumentException("Não foi possível autenticar no servidor FTP");
}
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.setCopyStreamListener(new CopyStreamAdapter()
{
#Override
public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize)
{
if(threadEnvio.isInterrupted())
{
try
{
ftp.abort();
}
catch(IOException ex)
{
handleException(ex);
}
}
else
{
int percent = (int) (totalBytesTransferred * 100 / arquivoSelecionado.length());
progressBar.setValue(percent);
}
}
});
fis = new FileInputStream(arquivoSelecionado);
if(ftp.storeFile(arquivoSelecionado.getName(), fis))
{
JOptionPane.showMessageDialog(null, "Arquivo enviado com suceso");
}
else
{
JOptionPane.showMessageDialog(null, "Não foi possível enviar o arquivo", "Erro", JOptionPane.ERROR_MESSAGE);
}
ftp.logout();
}
catch(Exception e)
{
handleException(e);
}
finally
{
if(fis != null)
{
try
{
fis.close();
}
catch(IOException ex)
{
handleException(ex);
}
}
if(ftp != null)
{
try
{
ftp.disconnect();
}
catch(IOException ex)
{
handleException(ex);
}
}
progressBar.setValue(0);
botaoEnviar.setEnabled(true);
botaoCancelar.setEnabled(false);
}
}
});
threadEnvio.start();
Cancel operation:
botaoCancelar.setEnabled(false);
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
threadEnvio.interrupt();
}
catch(Exception ex)
{
handleException(ex);
}
finally
{
botaoCancelar.setEnabled(true);
}
}
}).start();
interrupting a thread like this is not correct, it causes your thread to wait for some seconds at exactly which line that compiler is reading in your thread
the only way that you can abort your ftp upload is to make the thread sleep for some time
then abort your upload and wait for the thread to complete itself
see this :
try {
try {
Thread.currentThread();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
mFTP.abort();
} catch (IOException e) {
e.printStackTrace();
}
} catch (NetworkOnMainThreadException e) {
e.printStackTrace();
}

Categories