Restart myself - can I reinitialize everything from scratch? - java

I have something like this:
public static final String path;
static {
path = loadProperties("config.conf").getProperty("path");
}
public static void main(String... args) {
// ... do stuff (starting threads that reads the final path variable)
// someone want's to update the path (in the config.conf file)
restart(); // ???
}
I want to reinitialize the JVM calling the static initializer again, and then main(...)!
Can it be done?

You can start your application using a custom class loader, this will allow you to load and unload your static variables.
However, basically its a very bad design to need to do this. I like making fields final, but you shouldn't make them final if you want to change them.

If your goal is simply to reload some configuration files, why not implement a file change monitor?
Here's a good tutorial on this subject:
http://download.oracle.com/javase/tutorial/essential/io/notification.html
I think what you're proposing (restarting your application automatically) would be a little more cumbersome than just watching for file updates.

A simpler approach is simply not to use the static initializer for this. Why not just make path non-final and load it in main?

I'm accepting Peter Lawrey answer but post a complete example for anyone to use!
I'm not going to use this in production code... there are other ways of doing it!
public class Test {
public static void main(String args[]) throws Exception {
start();
Thread.sleep(123);
start();
}
private static void start() throws Exception {
ClassLoader cl = new ClassLoader(null) {
protected java.lang.Class<?> findClass(String name)
throws ClassNotFoundException {
try{
String c = name.replace('.', File.separatorChar) +".class";
URL u = ClassLoader.getSystemResource(c);
String classPath = ((String) u.getFile()).substring(1);
File f = new File(classPath);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte buff[] = new byte[(int) f.length()];
dis.readFully(buff);
dis.close();
return defineClass(name, buff, 0, buff.length, null);
} catch(Exception e){
throw new ClassNotFoundException(e.getMessage(), e);
}
}
};
Class<?> t = cl.loadClass("Test$Restartable");
Object[] args = new Object[] { new String[0] };
t.getMethod("main", new String[0].getClass()).invoke(null, args);
}
public static class Restartable {
private static final long argument = System.currentTimeMillis();
public static void main(String args[]) throws Exception {
System.out.println(argument);
}
}
}

how about this structure
public static void main(String... args) {
boolean restart = true;
while (restart )
{
retart = runApplication();
}
}
If you ever detect the need to restart you application, have runApplication return true.
If it is time to exit return false;

If you have an UI or a daemon so you can control output to stdout, you can make a wrapper on the outside that starts your program.
If the program upon exit outputs "RESTART" you can restart your program again from this wrapper. If not, it just ends.
Or if you want the pure java way, you can go with a solution with classloaders as Peter Lawrey mentioned in his post. Before going down this route you should really rethink your design (if it is your code) and make your code capable of cleaning itself up.

Related

Java: Call a main method from a main method in another class

I have a set of Java files in the same package, each having main methods. I now want the main methods of each of the classes to be invoked from another class step by step. One such class file is Splitter.java. Here is its code.
public static void main(String[] args) throws IOException {
InputStream modelIn = new FileInputStream("C:\\Program Files\\Java\\jre7\\bin\\en-sent.bin");
FileInputStream fin = new FileInputStream("C:\\Users\\dell\\Desktop\\input.txt");
DataInputStream in = new DataInputStream(fin);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine = br.readLine();
System.out.println(strLine);
try {
SentenceModel model = new SentenceModel(modelIn);
SentenceDetectorME sentenceDetector = new SentenceDetectorME(model);
String sentences[] = sentenceDetector.sentDetect(strLine);
System.out.println(sentences.length);
for (int i = 0; i < sentences.length; i++) {
System.out.println(sentences[i]);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (modelIn != null) {
try {
modelIn.close();
} catch (IOException e) {
}
}
fin.close();
}
}
I now want this to be invoked in AllMethods.java inside a main method.
So how can I do this? There are several other class files having main methods with IOException which have to be invoked in AllMethods.java file.
Update -
I have main methods having IOException as well as main methods not having IOEXception that has to be invoked in AllMethods.java.
You can do that. Main method is also just like any other static method
public static void main(String[] args) throws IOException {
....// do all the stuff
Splitter.main(args); // or null if no args you need
}
First of all, what you should probably do is refactor your code so each main method calls some other method, and then AllMethods makes calls to those new methods. I can imagine there might be some cases where it's useful if you're just trying to, for example, write some test code, but usually you wouldn't want to call main methods directly. It's just harder to read.
If you want to try it though, it's pretty easy, you just call the main method like any other static method. I once in college wrote a web server where, to handle authentication, I recursed on the main method. I think I got a C because it was unreadable code, but I had fun writing it.
class AllMethods {
public void callsMain() {
String[] args = new String[0];
Splitter.main(args);
}
}
In the Main.java, the main method should add throws Exception as shown below:
package com.company;
import java.io.FileNotFoundException;
public class Main extends makeFile {
public static void main(String[] args) throws FileNotFoundException {
makeFile callMakeFile = new makeFile();
makeFile.main(args);
// cannot figure out how to call the main method from the makeFile class here...
}
}

ServerSocket connection with more than one client

Folks. I'm newbie in network programming and come across the following issue. I need to write the server which can maintain a connection with more than one client simultaneously. What I've written is the following:
Main class:
public class Main {
public static void main(String args[]) throws Exception{
ConnectionUtils.waitForClients();
}
}
ConnectionUtils class:
public class ConnectionUtils {
private static ServerSocket server;
static{
try {
server = new ServerSocket(54321);
} catch (Exception e) {
}
}
private static Runnable acceptor = new Runnable() {
#Override
public void run() {
try {
Client c = new Client(server.accept());
new Thread(acceptor).start();
c.sendLine("Hello client \n");
} catch (Exception e) {
}
}
};
public static void waitForClients(){
Thread clientAcceptor = new Thread(acceptor);
clientAcceptor.start();
}
}
and it works, more-or-less. But what is the downside of that approach? I suspect there're too much disadvantage, but I can't catch their.
The problem is that you creating an infinite number of threads where threads are expensive resources. You should be using a ThreadPool to limit the number of threads created in your program.
Consider using Executors instead of using this low-level code, In Oracle documentation about Executors, there is an example similar to what you doing. Check it out!
Heh interesting. I wouldn't expect it to be wrong but it sure isn't how I'd write it.
I'd probably have 1 thread in an infinite (semi-infinite with stop condition) loop that accepts and spawn threads, rather than something that looks like a recursive method but isn't. However as far as I can see it's not wrong.
Having said that, if you don't use your main thread for anything, why not do something like (and keep in mind i'm not a network programmer either)
public class ConnectionUtils {
protected boolean stop = false;
public static void waitForClients() {
while (!stop) {
Client c = new Client(server.accept());
new Thread(new ClientDelegate(c)).start();
}
}
}
public static class ClientDelegate implements Runnable {
private Client client;
public ClientDelegate(Client c) { this.client = c; }
public static void run() {
c.sendLine("Hello client\n");
}
}

Java Code without Try and Catch

I have the code:
public class RssReader {
private File dataFile = new File("data.dat");
private FileInputStream dataStream = new FileInputStream("data.dat");
boolean fileExists;
public static void main(String[] args) {
}
}
My question is, can I put FileInputStream or any code that requires Try/catch as a global function?
Yes you can. you can declare that main method throws an Exception of any kind, i.e.
public static void main(String[] args) throws IOException {
}
And you can omit the try-catch block in the code.
I would highly suggest NOT doing that, though. First of all, try-catch blocks exist for a reason. They are here to catch exceptions that you might foresee but have no control of (i.e. bad file format). Second of all, they will let you close the streams in finally blocks even if the exception happens.
Yes you can if you let your constructor throws the exception :
class RssReader {
private File dataFile = new File("data.dat");
private FileInputStream dataStream = new FileInputStream("data.dat");
boolean fileExists;
RssReader()throws IOException{}
}
Then each time you will construct a new RssReader object, the method that handle this construction should throws it too (like darijan said), or you can create a try-catch block in this method :
public void someMethod() throws IOException {
RssReader r = new RssReader();
}
or :
public void someMethod() {
RssReader r;
try {
r = new RssReader();
} catch (IOException e) {
e.printStackTrace();
}
}
You may add that code by signing the method with throws Exception. But it is not recommended when you have an stream reader or something like that because often you gotta close the stream or flush the writers.
I think you should think about it when you need to open or close a stream object.
There are several things you can do and several you can't:
You can't initialize a variable with code that can throw a checked exception. The compiler will complain. So your line beginning private FileInputStream ... is illegal.
You can't use the instance variables inside the static main() method. The compiler will again complain once you put ... dataStream ... inside main().
You can put a throws IOException on the main method.
One way to deal with these things is to do this:
public class RssReader {
public static void main(String[] args) throws IOException {
File dataFile = new File("data.dat");
FileInputStream dataStream = new FileInputStream("data.dat");
boolean fileExists;
... use the variables here ...
}
}
which will toss you out to the command line if you run the program and, for example, the file doesn't exist. An error message and stack trace will be printed if that happens.
What I did up there is move all the variables into the scope of the main() method. Then I added the throws on the method so it will let whatever basic part of Java calls main() handle the exception.
Or you could do something another way like this:
public class RssReader {
private static File dataFile = new File("data.dat");
private static FileInputStream dataStream;
static {
try {
dataStream = new FileInputStream("data.dat");
} catch (IOException e) {
throw new RuntimeException(e); // this isn't a best practice
}
}
static boolean fileExists;
public static void main(String[] args) {
... use the variables here ...
}
}
which will do the same thing if there is a problem with finding the file. Out to the command line and print messages.
This hides the possible checked exception inside a static initializer block with a try-catch around it. The checked exception is turned into an unchecked exception. It also makes all the variable static so they can be used in the static method main()
One more possible solution that's an even better way:
public class RssReader {
private File dataFile = new File("data.dat");
private FileInputStream dataStream;
boolean fileExists;
public RssReader() throws IOException {
dataStream = new FileInputStream("data.dat");
}
public void doTheWork() {
... use all the variables here ...
}
public static void main(String[] args) {
try {
reader = new RssReader();
reader.doTheWork();
} catch (IOException e) {
System.out.printf("File 'data.dat' not found. Exiting ...");
}
}
}
which is the one I like best. It gives you control over what happens if an exception happens so we print an informative message and tell them the program is finished. All the variables are instance variables inside the object instance created in the main() method. Main does almost nothing but create the instance and tell it to get to work. Main also decides what to do if it fails.
The changes are to move everything to instance scope and out of static scope, except catching the fatal exception. You can leave your variables at the top where they are easy to read. The method that does the work is given a name to describe what it does.

JUnit Testing around Sytem.in and System.out

I have been asked to introduce unit test in a legacy Java Application that runs and operates from Command Line. Basically the main loop prints out a Menu, the user inputs something and it shows more data.
This Main class illustrate how the application works.
public class Main{
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
public static void main(String argv[]) throws IOException{
while (true) {
char input = (char) reader.read();
if(input == 'x'){
return;
}
System.out.println(input);
}
}
}
I'd like my test methods to look something like this
public void testCaseOne(){
Main.main();
String result = "";
result = sendInput("1");
assertEqual(result, "1");
result = sendInput("x");
assertEqual(result,"");
}
I am aware of the System.setOut() and System.setIn() methods, but I cannot figure out a way to make the System.setIn() method work in this context, since the reader.read() method is blocking my thread.
Is my test design wrong?
Is there a way to design the sendInput() method to work through the blocking reader.read() call?
I would suggest refactoring the code to allow the input/output streams to be injected, and then you can mock them. If you couuld change it to something like
public class Main{
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
public static void main(String argv[]) throws IOException{
new YourClass(reader,System.out).run();
}
}
public class YourClass { // I don't know what your class is actually doing, but name it something appropriate
private final InputReader reader;
private final PrintStream output;
public YourClass(InputReader reader, PrintStream output) {
this.reader = reader;
this.output = ouptut;
}
public void run() {
while (true) {
char input = (char) reader.read();
if(input == 'x')
return;
output.println(input);
}
}
This design does a couple of things:
It takes the logic out of your main class. Typically a main method is really just used for launching an application.
It makes YourClass more easily unit testable. In your tests, you can simply mock out the input/output.
Edit: Update to how this refactoring helps with the blocking IO problem
By making the reader/output injectable as shows above, you don't actually need to use the real System.in and System.out - you can use a mock instead. This eliminates the need to actually have blocking reads.
public void testCaseOne(){
// pseudocode for the mock - this will vary depending on your mock framework
InputReader reader = createMock(InputReader);
// the first time you read it will be a "1", the next time it will be an "x"
expect(reader.read()).andReturn("1");
expect(reader.read()).andReturn("x");
PrintStream stream = createMock(PrintStream);
// only expect the "1" to get written. the "x" is the exit signal
expect(stream.println("1"));
new YourClass(reader,stream).run();
verifyMocks();
}
I would refactor Main so it's easier to test.. like so:
public class Main{
private boolean quit = false;
public static void main(String[] argv) throws IOException {
Main main = new Main();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
char input = main.readInput(reader);
while (!main.quit()) {
System.out.println(input);
input = main.readInput(reader);
}
}
public char readInput(Reader reader) throws IOException{
char input = (char) reader.read();
if(input == 'x'){
quit = true;
return '\0';
}
return input;
}
public boolean quit(){
return quit;
}
}
Personally, I try to stay away from static variables. If you need one you could always declare it in the main method like above.
Testing the while(true) is pretty much impossible because testing if the while loop never quits would take an infinite amount of time. Then there is the question if you should test the quitting of the loop in the main.quit() == true case. Personally, I would just test the core logic and leave the rest untested:
public class MainTest {
private Main main;
#Before
public void setup(){
main = new Main();
}
#Test
public void testCaseOne() throws IOException{
char result1 = main.readInput(new StringReader("1"));
assertEquals(result1, '1');
assertFalse(main.quit());
char result2 = main.readInput(new StringReader("x"));
assertEquals(result2, '\0');
assertTrue(main.quit());
}
}
Here is the solution I went with that required no refactoring of the legacy code.
In a nutshell, I made an Abstract Test Class that compiles and execute the Application in a Process on a seperate thread. I attach myself to the Input/Output of the Process and read/write to it.
public abstract class AbstractTest extends TestCase{
private Process process;
private BufferedReader input;
private BufferedWriter output;
public AbstractTest() {
//Makes a text file with all of my .java files for the Java Compiler process
Process pDir = new ProcessBuilder("cmd.exe", "/C", "dir /s /B *.java > sources.txt").start();
pDir.waitFor();
//Compiles the application
Process p = new ProcessBuilder("cmd.exe", "/C", "javac #sources.txt").start();
p.waitFor();
}
protected void start(){
Thread thread = new Thread() {
public void run() {
//Execute the application
String command = "java -cp src/main packagename.Main ";
AbstractTest.this.process = = new ProcessBuilder("cmd.exe", "/C", command).start();
AbstractTest.this.input = new BufferedReader(new InputStreamReader(AbstractTest.this.process.getInputStream()));
AbstractTest.this.output = new BufferedWriter(new OutputStreamWriter(AbstractTest.this.process.getOutputStream()));
}
}
}
protected String write(String data) {
output.write(data + "\n");
output.flush();
return read();
}
protected String read(){
//use input.read() and read until it makes senses
}
protected void tearDown() {
this.process.destroy();
this.process.waitFor();
this.input.close();
this.output.close();
}
}
Afterward, it was pretty easy to make actual test class and implement real test methods.
public void testOption3A(){
start();
String response = write("3");
response = write("733");
assertEquals("*** Cactus ID 733 not found ***",response);
}
Pros
No refactoring needed
Actually testing the implementation (No Mocking/Injection)
Doesn't require any external librairies
Cons
Pretty hard to debug when things aren't working proprely (Fixable)
Rely heavily on OS behavior (Windows in this class, but Fixable)
Compiles the application for every test class (Fixable I think?)
"Memory Leak" when there is an error and the process is not killed
(Fixable I think?)
This is probably a borderline "hack", but it met my needs and demands.

Does java have an equivalent to the C# "using" clause

I've seen reference in some C# posted questions to a "using" clause.
Does java have the equivalent?
Yes. Java 1.7 introduced the try-with-resources construct allowing you to write:
try(InputStream is1 = new FileInputStream("/tmp/foo");
InputStream is2 = new FileInputStream("/tmp/bar")) {
/* do stuff with is1 and is2 */
}
... just like a using statement.
Unfortunately, before Java 1.7, Java programmers were forced to use try{ ... } finally { ... }. In Java 1.6:
InputStream is1 = new FileInputStream("/tmp/foo");
try{
InputStream is2 = new FileInputStream("/tmp/bar");
try{
/* do stuff with is1 and is 2 */
} finally {
is2.close();
}
} finally {
is1.close();
}
Yes, since Java 7 you can rewrite:
InputStream is1 = new FileInputStream("/tmp/foo");
try{
InputStream is2 = new FileInputStream("/tmp/bar");
try{
/* do stuff with is1 and is2 */
} finally {
is2.close();
}
} finally {
is1.close();
}
As
try(InputStream is1 = new FileInputStream("/tmp/foo");
InputStream is2 = new FileInputStream("/tmp/bar")) {
/* do stuff with is1 and is2 */
}
The objects passed as parameters to the try statement should implement java.lang.AutoCloseable.Have a look at the official docs.
For older versions of Java checkout this answer and this answer.
The nearest equivalent within the language is to use try-finally.
using (InputStream in as FileInputStream("myfile")) {
... use in ...
}
becomes
final InputStream in = FileInputStream("myfile");
try {
... use in ...
} finally {
in.close();
}
Note the general form is always:
acquire;
try {
use;
} finally {
release;
}
If acquisition is within the try block, you will release in the case that the acquisition fails. In some cases you might be able to hack around with unnecessary code (typically testing for null in the above example), but in the case of, say, ReentrantLock bad things will happen.
If you're doing the same thing often, you can use the "execute around" idiom. Unfortunately Java's syntax is verbose, so there is a lot of bolier plate.
fileInput("myfile", new FileInput<Void>() {
public Void read(InputStream in) throws IOException {
... use in ...
return null;
}
});
where
public static <T> T fileInput(FileInput<T> handler) throws IOException {
final InputStream in = FileInputStream("myfile");
try {
handler.read(in);
} finally {
in.close();
}
}
More complicated example my, for instance, wrap exceptions.
It was a long time coming but with Java 7 the try-with-resources statement was added, along with the AutoCloseable interface.
Not that I'm aware of. You can somewhat simulate with a try...finally block, but it's still not quite the same.
The closest you can get in Java is try/finally. Also, Java does not provide an implicit Disposable type.
C#: scoping the variable outside a using block
public class X : System.IDisposable {
public void Dispose() {
System.Console.WriteLine("dispose");
}
private static void Demo() {
X x = new X();
using(x) {
int i = 1;
i = i/0;
}
}
public static void Main(System.String[] args) {
try {
Demo();
} catch (System.DivideByZeroException) {}
}
}
Java: scoping the variable outside a block
public class X {
public void dispose() {
System.out.println("dispose");
}
private static void demo() {
X x = new X();
try {
int i = 1 / 0;
} finally {
x.dispose();
}
}
public static void main(String[] args) {
try {
demo();
} catch(ArithmeticException e) {}
}
}
C#: scoping the variable inside a block
public class X : System.IDisposable {
public void Dispose() {
System.Console.WriteLine("dispose");
}
private static void Demo() {
using(X x = new X()) {
int i = 1;
i = i/0;
}
}
public static void Main(System.String[] args) {
try {
Demo();
} catch (System.DivideByZeroException) {}
}
}
Java: scoping the variable inside a block
public class X {
public void dispose() {
System.out.println("dispose");
}
private static void demo() {
{
X x = new X();
try {
int i = 1 / 0;
} finally {
x.dispose();
}
}
}
public static void main(String[] args) {
try {
demo();
} catch(ArithmeticException e) {}
}
}
I think you can achieve something similar to the "using" block, implementing an anonymous inner class. Like Spring does with the "Dao Templates".
Well, using was syntactic sugar anyway so Java fellows, don't sweat it.
If we get BGGA closures in Java, this would also open up for similar structures in Java. Gafter has used this example in his slides, for example:
withLock(lock) { //closure }
The actual idiom used by most programmers for the first example is this:
InputStream is1 = null;
InputStream is2 = null;
try{
is1 = new FileInputStream("/tmp/bar");
is2 = new FileInputStream("/tmp/foo");
/* do stuff with is1 and is 2 */
} finally {
if (is1 != null) {
is1.close();
}
if (is2 != null) {
is2.close();
}
}
There is less indenting using this idiom, which becomes even more important when you have more then 2 resources to cleanup.
Also, you can add a catch clause to the structure that will deal with the new FileStream()'s throwing an exception if you need it to. In the first example you would have to have another enclosing try/catch block if you wanted to do this.
No there isn't.
You can
public void func(){
{
ArrayList l = new ArrayList();
}
System.out.println("Hello");
}
This gives you the limited scope of the using clause, but there isn't any IDisposable interface to call finalization code. You can use try{}catch(){}Finally{}, but it doesn't have the sugar of using. Incidentally using finalizers in Java is generally a bad idea.
No, there is no using in Java, the most similar functionality is the "import" keyword.

Categories