Problems when calling strings from other methods - java

I have a declared a String with the class as follows:
public static String nixprocessvalue;
I assign some data to the string with this method:
public static void GetStatsNix(String operation)
{
String result = null;
try {
Runtime r = Runtime.getRuntime();
Process p = r.exec("/bin/hostname");
BufferedReader in =
new BufferedReader(new InputStreamReader(p.getInputStream()));
String inputLine;
inputLine = in.readLine();
}

For your question you should try to concentrate on the important points, in your case the changes you make to the variable in question.
Because it's not a general problem of scope - consider this simple example:
public class StaticTest {
public static String s;
public static void main(String[] args) {
write();
read();
}
static void write() {
s = "Hello";
}
static void read() {
System.out.println(s);
}
}
The static variable is written and read in two different methods, which is perfectly fine.
The question is, why you declare everything static - just because you do everything from main and don't feel like making object instances is a good idea in java or has it a special reason?

} catch (IOException e) {
System.out.println(e);
} public static void GetStatsNix(String operation)
{
This last line looks very suspicious to me, because your actual function isn't closed yet, but another method definition is started (GetStatsNix(String operation)).
Are you sure, that you don't have some wrong placed brackets?

Related

When should i create inner class or inner static class?

I am aware about the static keyword, but in short. My attempt is to create inner static class since it's related to outer class. The practical problem is I am confused how to access it. My reason use static class is that I just need one instance of it per application?
Please correct if you found any misconseption, and give real usage of the class / static class.
public class DbPredecessorTest {
List<Book> db;
Book book;
Integer numberOfBooks;
static BufferedReader reader;
static {
try {
reader = new BufferedReader(new FileReader(Main.fileLoc));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
static class Helper {
DbPredecessor dbPredecessor= new DbPredecessor();
Long getLines() {
return reader.lines().count();
}
}
My directionless attempt:
class SomeTest {
#Test
void ableToSave() throws IOException {
db.add(book);
boolean save = Helper.dbPredecessor.save(db);
assertEquals(true, save);
}
#Test
void save_should_increaseLine() throws IOException {
db.add(book);
// numberOfBooks= (int) Helper.get
boolean save = dbPredecessor.save(db);
assertEquals(numberOfBooks+1, reader.lines().count());
}
}
That's not the reason to use a static inner class. A static inner class is functionally an ordinary Java class, the only real reason you would have one is to indicate it's related to the outer class in some way or to make it private.
You could just use a normal static method here:
public class DbPredecessorTest {
static long getLines() {
return reader.lines().count();
}
}
and then use it like so:
long numberOfBooks = DbPredecessorTest.getLines();

How to test function which calls another void function from it with static value as argument using mockito

I have a class A as
Class A{
private static final String ANON_DIR = "/webapps/worldlingo/data/anonymizer/";
private static final String NO_ANON = "noanonymize";
public String first(String text, String srclang, Map dictTokens) {
Set<String> noAnonymize = new HashSet<String>();
second(noAnonymize,ANON_DIR + NO_ANON, "tmpLang","name");
String value;
if(noAnonymize.contains("test")){
value = word;
}
else {
value = "test";
}
return value;
}
where ANON_DIR and NO_ANON is static final value. This class has function first and function second .The first function has a calling method in it which calls second function. The second function is void function which takes static fields as parameter.
Second function is just the file read function with the path provided as
private void second (Set<String> hashSet, String path, String lang , String type) {
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(path);
br = new BufferedReader(fr);
String Line;
while ((Line = br.readLine()) != null) {
hashSet.add(Line);
}
} catch (IOException e) {
log.error("Anonymizer: Unable to load file.", e);
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
} catch (IOException e) {
log.error("Anonymizer : An error occured while closing a resource.", e);
}
}
}
}
Now I am trying to test the function first using mockito. I am trying to change the static parameter and send those changed static parameter as
public void testfirst() throws Exception {
A anon = new A();
Field ANON_DIR = A.class.getDeclaredField("ANON_DIR");
ANON_DIR.setAccessible(true);
//java relection to change private static final field
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(ANON_DIR, ANON_DIR.getModifiers() & ~Modifier.FINAL);
ANON_DIR.set(null,"test");
Field NO_ANON = A.class.getDeclaredField("NO_ANON");
NO_ANON.setAccessible(true);
Field modifiersField1 = Field.class.getDeclaredField("modifiers");
modifiersField1.setAccessible(true);
modifiersField1.setInt(NO_ANON, NO_ANON.getModifiers() & ~Modifier.FINAL);
NO_ANON.set(null,"/noanonymize");
Method anonymizeNames = anon.getClass().getDeclaredMethod("first", String.class, String.class , Map.class);
String srcLang = "MSFT_EN";
Map mapTokens = new HashMap();
String result = (String) anonymizeNames.invoke(anon,"I am David",srcLang,mapTokens);
}
PROBLEM:
Here I could change the private final static field ANON_DIR and NO_ANON using java reflection but the changed field are not send to the second function. The second function called from first function takes the original value instead of changed value. i.e when the second is called ANON_DIR has
"/webapps/worldlingo/data/anonymizer/" value instead of "test".
Since I changed the value of ANON_DIR to "test" I want the same "test" value to be passed to the second function. How can I acheive this for testing for void second method.
The problem here is the violation of the Separation of concerns principle.
Your code under test (cut) does too much and thus you have a hard time to find seams to replace dependencies.
Also there is a misunderstanding of the aim of unittests. You don't test code, you test public observable behavior which is any return value and communication with dependencies (but not necessarily public methods).
So my suggestion is to move method second() to a new class of its own. The cut gets an instance of this new class passed in as constructor parameter.
Then it is easy to replace the real dependency with a mock of that new class in your test.
On the other hand you could simple surrender to your bad design by using PowerMock...

Data operation in memory

I know it is always better to operate data in memory instead of file. Currently, I am putting all incoming data in a static ArrayList, and when that ArrayList has more than 80 entries, my program will save the contents of this ArrayList to a file and clear up this array for the next wave of coming data.
I wonder if it's better (or worse) to use Vector instead of ArrayList. If there is difference, which is better/worse? And in which case?
Here is my relevant code:
public class Exchange () {
private static ArrayList<String> datain = new ArrayList<String> ();
public static void addData(String s) {
datain.add(s);
}
public static boolean checkSize() {
if (datain.size() >= 80)
return true;
else
return false;
}
public static void writeData() throws FileNotFoundException {
PrintWriter pw = new PrintWriter(new File ("myfile.txt"));
for (int i = 0; i < datain.size(); i++) {
pw.println(datain.get(i);
}
pw.close();
}
public static void clear() {
datain = new ArrayList<String>();
}
}
P.S. This approach currently works fine, I am just wondering whether using vector will be better for this case. Also, if you see any bad design, feel free to point it out. Thanks!
In the vast majority of cases, using ArrayList will suffice. The primary difference is that Vector is thread-safe, whilst ArrayList is not, but seeing as you aren't working with multiple threads, there is no reason to prefer Vector over ArrayList in your code
This is how I would do it, unless I know there is a performance issue. Most of the cost is in the opening and closing of the file, so I would avoid doing that. I would also assume that appending is what you want.
public enum Logging {
; // no instances
public static final String FILE_NAME = "myfile.txt";
private static final PrintWriter pw;
static {
try {
pw = new PrintWriter(new FileWriter(FILE_NAME, true));
} catch (IOException ioe) {
throw new AssertionError(ioe);
}
}
public static void addData(String s) {
pw.println(s);
}
}

Strange Java error placement

Still working on the same project (Java-based shell) and tried to run it - and got a strange error. I was working with a single class that represents one of the commands, and, because of the fact that school computers have no compilers, I use ideone. Anyway, I am getting an error and, while I have seen it before, the placement is really weird. The error:
Main.java:56: error: no enclosing instance of type LIST_Command is in scope
public FAKE_CMD(int i) {this.msg = i;System.out.println(i);}
^
Shouldn't this be in a place that is CALLING the constructor, or a static method of the class?
And here is the code (in its entirety, let me know what I should trim or edit it out yourself) Yes, this makes it an SSCCE.
package javashell.ver2.command;
import java.io.*;
import java.util.*;
class LIST_Command { /*extends Command*/
public static Map<String, Command> commands = new HashMap<>();
public String description() {
return "List all commands, their descriptions, or usages.";
}
public String usage() {
return "list <cmds | desc | usage>";
}
public boolean runCmd(String[] cmdArgs, PrintStream output) {
try {
if (cmdArgs.length == 0) {
return false;
}
else if (cmdArgs.length > 0) {
if (cmdArgs[0].equals("cmds")) {
for (Map.Entry<String, Command> cmd : /*main.Main.*/commands.entrySet()) {
output.println(cmd.getKey());
}
}
else if (cmdArgs[0].equals("desc")) {
for (Map.Entry<String, Command> cmd : /*main.Main.*/commands.entrySet()) {
output.println(cmd.getValue().description());
}
}
}
return true;
}
catch (Exception e) {
return false;
}
}
public static void main(String[] args) {
commands.put("test1", new FAKE_CMD(1));
commands.put("test2", new FAKE_CMD(2));
new LIST_Command().runCmd(new String[] {"cmds"}, System.out);
}
abstract class Command {
public abstract String usage();
public abstract String description();
public abstract boolean runCmd(String[] cmdArgs, PrintStream output);
}
static class FAKE_CMD extends Command {
int msg;
public FAKE_CMD(int i) {
this.msg = i;
System.out.println(i);
}
public String usage() {
return "usagetest" + msg;
}
public String description() {
return "descriptiontest" + msg;
}
public boolean runCmd(String[] cmdArgs, PrintStream output) {
return true;
}
}
}
Command is an inner class, which doesn't seem to make sense since it is contained in a class that should be its subclass. Anyway, that is the cause of your error: regardless of whether FAKE_CMD is itself static or not, it needs an enclosing instance of LIST_Command since it extends Command.
Note a possible subtlety in Java's terminology: inner class means a non-static nested class, therefore it implies the need for an enclosing instance.
The constructor of FAKE_CMD need to call its superclass' (Command's) constructor. However, since the superclass is not static, Java has no way of instantiate a superclass instance before constructing a FAKE_CMD.

Java static fields not working with inheritance

Alright, this is probably something simple, but I just can't get it.
package foo.foo.foo;
public class Vars {
public static boolean foo = false;
}
Alright, so that's my Vars class.
I then have a JFrame, with a JMenuBar,JMenu,and a JMenuItems.
items = new JCheckBoxMenuItem("Foo");
items.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
AbstractButton ab = (AbstractButton)e.getSource();
Vars.foo = ab.getModel().isSelected();
System.out.println(Vars.foo);
}
});
menu.add(items, 0);
menuBar.add(menu,0);
All is good, it returns true for the println.
Now, this is the actual problem part...
I have a if statement
if(Vars.foo)
This -should- work, right? It never executes the code inside the if brackets, UNLESS I add this line of code above it.
System.out.println(Vars.foo);
That naturally prints true, then the if statement works, but if I comment out that line, it doesn't work.
I've also been googling, and tried this:
Vars v = null;
if(v.yoo)
That still won't do it unless I have the println, I have no idea why the println makes it work. Can you explain why/how this works?
Edit:
public class painthandling implements Runnable {
#Override
public void run() {
Vars y = null;
while(true){
if(y.foo){
//some code here
}
System.out.println(y.foo);
}
}
}
That's the part that's not working, the if statement. always returns false.
frame f = new frame();
(new Thread(new painthandling())).start();
System.out.print("Got it.");
The JFrame part is called in the new frame, then the other class is called there, with the Vars class called in both. in painthandling(), the if statement returns false if it doesn't have the println.
Short answer: Make the variable volatile
Long answer:
I have done some testing, and I can actually reproduce your situation (at least I think it's the same). Consider this code:
public class Test {
public static boolean foo = false;
public static void main(String[] args) {
new Thread(new Runnable(){
#Override
public void run() {
while(true) {
try {
Thread.sleep(2000);
System.out.println("Swapping");
Test.foo = !Test.foo;
}
catch(Exception e) {
e.printStackTrace();
}
}
}
}).start();
while(true) {
if(Test.foo) {
System.out.println("I'm here");
}
}
}
}
This never prints I'm here. However, as the OP states, adding a System.out.println to the while loop does make it print it. But interestingly enough, it can be any println statement. It doesn't need to print the variable value. So this works:
public class Test {
public static boolean foo = false;
public static void main(String[] args) {
new Thread(new Runnable(){
#Override
public void run() {
while(true) {
try {
Thread.sleep(2000);
System.out.println("Swapping");
Test.foo = !Test.foo;
}
catch(Exception e) {
e.printStackTrace();
}
}
}
}).start();
while(true) {
if(Test.foo) {
System.out.println("I'm here");
}
System.out.println(""); // Doesn't have to be System.out.println(Test.foo);
// This also works (lock is just an object)
// synchronized(lock) {
// int a = 2;
// }
}
}
}
There are some other cases that also produces the "expected" output, and that is making the variable volatile, or doing a Thread.sleep() inside the while loop where the test is done. The reason it works when the System.out.println is probably because println is synchronized. And in fact, doing any synchronized operation inside the loop have the same effect. So to conclude, it's a threading (memory model) issue, and it can be resolved by marking the variable as volatile. But this does not change the fact that doing multithreaded access with a static variable is a bad idea.
I suggest reading Chapter 17 of the Java Language Specification to learn more about threads, synchronization and the Java memory model.
I didn't really read your post but after skimming it looks like you are trying to use the static method like this.
someMethod() {
Var var = null;
boolean bool = var.foo
}
The nice thing about static method and fields is that you don't have to instantiate them, try this instead:
someMethod() {
boolean bool = Var.foo
}

Categories

Resources