I am really new to java (started learning 2 days ago). Sorry if this is a stupid question. I am trying to learn how to use rt.exec & similar methods so I tried to make a very simple program which runs calc.exe. This is the code:
public class main {
{
try {
Runtime rt = Runtime.getRuntime() ;
Process p = rt.exec("calc.exe") ;
}
catch(Exception exc){/*handle exception*/}
}
}
I get the error " The value of local variable p is not used".
And if I try to compile this is what I get:
I think it's easy to fix but I don't know how. Would be nice if someone helped.
Well, the error "The value of local variable p is not used.", Is not actually an error. It's your IDE (Eclipse), warning you that you aren't actually reading that variable, so you aren't receiving any input from it.
And the other problem with your class is, you don't have a main method. Like this,
public class main {
public static void main(String[] args) {
try {
Runtime rt = Runtime.getRuntime() ;
Process p = rt.exec("calc.exe") ;
} catch(Exception exc){
/*handle exception*/
}
}
}
And by the way, you should always start a class name with a captial letter. So public class main, should actually be public class Main
You get that error because you don't have the main method that is used to start the java program:
public class main {
public static void main(String[] args) {
try {
Runtime rt = Runtime.getRuntime() ;
Process p = rt.exec("calc.exe") ; // here, eclipse is WARINING(so you can ignore it) you that that the variable p is never used(it's just a warning)
} catch(Exception exc) {
/*handle exception*/
// never do this, always put at least a System.out.println("some error here" + e); so you don't ignore a potential exception
}
}
I believe what you have is not an error but a warning; eclipse (and other IDEs/compilers) will tell you that, although you assigned a value to the variable p, you did not use it anywhere. It tells you this because this is sometimes an error; mostly when you assign a value to a variable, you later use that variable in some way.
You can eliminate the error by changing that particular statement to just
rt.exec("calc.exe")
since you are not required to assign a value from the call to exec.
There is no such thing as a stupid qiestion(only misplaced ones, in the worst case).
The "Editor does not contain a main type" refers to the fact that you have not defined a main method. All java programs require a main method, as such:
public static void main(String [] args){
<code>
}
This is where you must place your code.
The "Value not used" is just a warning; it tells you that your variable p only exists within the try-block. You can declare your p-variable before the try - that way, you can use it outside the try-scope(the scope of a variable refers to where it exists, in this case, only inside the try-block).
If you want to use your p, this is what you're after:
public class Main {
public static void main(String[] args) {
Process p;
try {
Runtime rt = Runtime.getRuntime();
p = rt.exec("calc.exe");
} catch(Exception exc) {/*handle exception*/}
}
}
[EDIT]: Note that it is part of the java coding convention to use Capital letters for the first letter of a class, e.g. Main.java(not main.java)
The use of the variable is not in issue here. That error appears because JVM needs a method with the signature to know where to start execution.
public static void main( String args[] ){ //TODO: Stuff here }
Introduce a method with this signature in your class, and it shall clear that error.
Alternatively, you may embed your code in a static block as below - but this method is not to be recommended.
static {
// TODO: Your code here
}
Error "The value of local variable p is not used" due to the fact that nowhere in the code, you do not use the variable p.
To remove the error - it is necessary to remove the variable "p".
To run the calculator, you must use the code:
public class MainClass {
public static void main(String args[]) throws IOException {
Runtime.getRuntime().exec("cmd /c calc.exe");
}
}
This and all other comments translated by Google Translate
you are not using main how can you compile please use main method.
Ans second one is use p local variable in your method.other wise declare p variable starting of method.
Related
I am working on a homework assignment that takes input from a .csv file and will prompt the user for different questions pertaining to the information contained within (crime statistics).
My code is as follows and it's still really early so I just have some placeholder variables in there as I have been wracking my head trying to figure out the best approach to this problem.
import java.io.*;
public class USCrimeArray {
String crimeArray[][] = new String[21][20];
public void createCrimeArray() throws Exception{
String crimeArrayInputString;
int crimeArrayRowValue = -1;
try (BufferedReader crimeArrayInput = new BufferedReader(new FileReader("C:/Users/Joey/Documents/Crime.csv"))) {
while ((crimeArrayInputString = crimeArrayInput.readLine()) != null) {
crimeArrayRowValue++;
crimeArray[crimeArrayRowValue] = crimeArrayInputString.split(",");
}
} catch (IOException io) {
io.getMessage();
}
}
public USCrimeArray(){
String[][] thisArray = crimeArray.clone();
}
public String[][] getCrimeArray(){
return crimeArray.clone();
}
}
This is the code for my first class and if I do a deepToString inside of createCrimeArray I get the information back that I want. The constructor for USCrimeArray hasn't really been thought out yet my main question is how to write the information to the crimeArray[][] so that I can carry it back over to other classes.
Once again this test main hasn't been thought out too far because I am still struggling with why my method is not writing over the crimeArray[][] with the while loop and it is as follows:
import java.util.Arrays;
public class USCrimeClass {
public static void main(String[] args) {
USCrimeArray crimeArray = new USCrimeArray();
String[][] test = crimeArray.getCrimeArray();
System.out.println(Arrays.deepToString(test));
}
}
I know there's a lot I'm doing wrong here, but this is the end result so far after having altered everything over and over again and not making any progress. The result of the system out in this is obviously just a 21x20 array of null elements. Any help would be greatly appreciated.
You need to call createCrimeArray() in USCrimeClass
public class USCrimeClass {
public static void main(String[] args) {
USCrimeArray crimeArray = new USCrimeArray();
crimeArray.createCrimeArray();
String[][] test = crimeArray.getCrimeArray();
System.out.println(Arrays.deepToString(test));
}
}
Also,
in the constructor of USCrimeArray you are clonning the array into a local variable thisArray but never use it. this is redundant and can be safely removed.
in getCrimeArray() you are returning a clone of the array. this is not needed (unless you want to keep USCrimeArray immutable). you can just return the array itself
Instance variables
instance variables are non static class level variables (much like crimeArray).
One can consider instance variables as serving two purposes:
"details" of the problem domain of the class. For example Person class will have instance variables such as firstName and lastName that are details of one person.
"configuration" variables holding information related to the technological environment and not pertaining to the problem domain of the class. For example, one sometimes might find a class with a boolean deleted instance variable that signifies a "soft deleted" instance that is not to be presented to the user or included in calculations. the purpose behind this is to support undo of deletion.
so crimeArray is of category details of USCrimeArray. common best practice is to initialise instance variables in the class constructor, so by the time you finish creating a new instance, you have one that has full and valid details. So I would move all of the code of createCrimeArray() into the constructor.
If you need to modify an instance variable after it was initialised, then a "setter" method can be used. these have a standardized signature: public void setCrimeArray(crimeArray[][]). having a standardized signature allows your class to be used by frameworks and libraries that add functionality. For example, storing the data in a relational database, sending/recieving the data over the internet, etc.
Now, I see that the external input that is used to populate the array comes from a file. The way it is coded now, USCrimeArray can only read one specific file from predetermined file syatem location. a more flexible way would be for the class to receive the specification for external input as an argument:
public USCrimeArray(String filename) {
...
try (BufferedReader crimeArrayInput = new BufferedReader(new FileReader(filename))) {
...
}
now the same class can be used to process an array from different files.
now you can even make the file name an argument of the java program:
public class USCrimeClass {
public static void main(String[] args) {
USCrimeArray crimeArray = new USCrimeArray(arg[0]);
System.out.println(Arrays.deepToString(test));
}
}
now the same java program can process different files without need for recompile.
I'm working on a program that uses JavaFx to display icons in a list.
I've made a static class used to look up specific ids from a txt document. Originally, the static block would add the id and name of an item defined on each line, but since these issues arose, I've tried to find the source of the issue.
Instead, I've just gone through the text file's content in the static block and have printed it out to the console.
This is my code for reference:
public class ItemIds {
public static int UNDEFINED_ID = -1;
private static HashMap<String, Integer> items;
static {
items = new HashMap<String, Integer>();
System.out.println(new File("res/ids/item ids.txt").exists());
try {
//should print out every line in the text file
Files.lines(Paths.get("res/ids/item ids.txt")).forEach(s -> {
System.out.println(s);
});
} catch (IOException e) {
System.out.println("Unable to read specified file.");
e.printStackTrace();
}
}
public static int getId(final String name) {
final Integer id = items.get(name);
return id != null ? id : UNDEFINED_ID;
}
}
However, what I do get when this static class is initialized and the static block is invoked is quite odd. It lists every single line without error until it gets to line 10691, where it throws "Exception in thread "JavaFX Application Thread" java.lang.ExceptionInInitializerError".
What makes this particularly weird, however, is that when I work with a smaller text document (with less entries), everything seems to work fine. Since the file is comprised of almost 14000 lines, I have to delete ~4000 lines for it to be able to work.
Any ideas on why it would be doing this? Any feedback is appreciated - thank you
I am unable to reproduce this error. I have created a file with 18K lines and you program just works fine with that. So, definitely consider reviewing your file and also the stack trace.
Now coming back to your exception ExceptionInInitializerError, the following is a possible:
ExceptionInInitializerError signals that an unexpected exception has occurred in a static initializer. An ExceptionInInitializerError is thrown to indicate that an exception occurred during evaluation of a static initializer or the initializer for a static variable.
class ItemIds
{
static
{
// if something does wrong -> ExceptionInInitializerError
}
}
Because static variables are initialized in static blocks there is a potential for introducing errors too. An example:
class ItemIds
{
static int v = D.foo();
}
=>
class ItemIds
{
static int v;
static
{
v = D.foo();
}
}
So if foo() goes crazy then you can get a ExceptionInInitializerError.
Have you presented your complete code in static block?
System.out.println("A read operation on a field is encountered ");
How can I add a statement, lets say , the above statement ,
whenever a read operation has been performed on a non-local field ?
and also I need to know the details of the field which is read and the set of
details should correspond to the uniqueness of the field
Example (to remove abstraction in the question):
public class Greet{
int knowncount;
public Greet()
{
System.out.println("Hello");
knowncount++;
}
public Greet(String language)
{
if(String.equals("ENGLISH")) {System.out.println("Hello"); knowncount++; }
else if(String.equals("SPANISH")) {System.out.println("Hola"); knowncount++;}
else System.out.println("Language not recognized");
}
public void showCount()
{
System.out.println("count : "+knowncount);
}
}
and the user class test is:
class test{
public static void main(String[] args){
Greet g("SPANISH");
g.showCount();
}
}
in the above example after using javassist our code should output :
A read operation on a field is encountered
1
You can do what you ask by using Javassist's ExprEditor. ExprEditor allows you to edit what is done in a FieldAccess, to implement your request you can create an injector that does the following:
ClassPool classPool = ClassPool.getDefault();
CtClass greetCtClass = classPool.get(Greet.class.getName());
greetCtClass.instrument(new ExprEditor() {
#Override
public void edit(FieldAccess fieldAccess)
throws CannotCompileException {
if (fieldAccess.getFieldName().equals("knowncount")) {
fieldAccess
.replace(" { System.out.println(\"A read operation on a field is encountered \"); $_ = $proceed($$); } ");
}
}
});
greetCtClass
.writeFile("<ROOT DIRECTORY WHERE THE CLASSES ARE>");
Best way to explain parameter is with an example, imagine that Greet class (that happens to be in the greatPackage) is in the following path /home/user/dev/proj1/build/greetPackage/Greet.class. In this scenario your root directory will be /home/user/dev/proj1/build/.
The line of interest in all the boiler plate above is the following:
{ System.out.println(\"A read operation on a field is encountered \"); $_ = $proceed($$); }
What is happening here?
First notice that all code is between curly brackets, if you know your way in javassist this is something trivial to you, if not it might make you loose a few minutes trying to understand what is wrong.
Then you have the System.out you requested
Finally you have a magic line: $_ = $proceed($$);. You can find more information about this in the javassist tutorial (search for FieldAccess in that section, since they don't have a direct anchor for it, sorry!) but basically what this line is saying is that the resulting value of the field access is the the value of the virtual method that's being invoked for the field access, so in other words the actual value of the field.
Keep in mind that you have to rewrite your Greet class with the injector in a separated JVM process and only afterwards you'll be able to use the class with the injected behavior, unless you do some tricks with classloading to make sure you load the modified version. I'm not going into those topics because it's out of the scope, but if you need help with that as well please say so. I'll gladly help you out.
I'm working on localization for a program I've written with a couple other guys. Most of the strings now load in the appropriate language from an ini file. I'm trying to do the same with the format of currency in the program. However, I'm getting a runtime exception as soon as I attempt to launch the application.
I'm using the Locale object as a parameter to a few NumberFormat.getCurrencyInstance()'s, like so:
private static final NumberFormat decf;
static
{
decf = NumberFormat.getCurrencyInstance(Lang.cLocale);
decf.setRoundingMode(RoundingMode.HALF_UP);
}
Lang is the class which contains all the localization stuff. The code the IDE complains about at attempted runtime is public static Locale cLocale = new Locale(GUI.DB_info[19],GUI.DB_info[20]);
GUI is the class the GUI is contained in, and where we decided to construct the DB_info array (which itself just contains information loaded from a remote database in another class). DB_info[19] is the language code (es right now) and DB_info[20] is the country code (US). The array elements are being properly filled-- or were, I can't get far enough into the program to tell right now; but nothing has changed with the code for filling DB_info.
The full exception is as follows:
Exception in thread "main" java.lang.ExceptionInInitializerError
at greetingCard.GUI.<clinit>(GUI.java:118)
Caused by: java.lang.NullPointerException
at java.util.Locale.<init>(Unknown Source)
at java.util.Locale.<init>(Unknown Source)
at greetingCard.Lang.<clinit>(Lang.java:13)
... 1 more
The line in GUI referenced is: static String welcome = Lang.L_WELCOME + ", " + empName;, and Lang.java basically looks like this:
// Set locale for currency display
public static Locale cLocale = new Locale(GUI.DB_info[19],GUI.DB_info[20]); // language, country
// Employee specific strings
public static String L_AMT_REMAIN = "";
public static String L_AMT_TEND = "";
public static String L_APPROVED = "";
public static String L_ARE_YOU_SURE = "";
[...]
public static void Main(String emp_lang)
{
String header = "";
if (emp_lang.equals("ENG"))
{
header = "ENG";
}
else if (emp_lang.equals("SPA"))
{
header = "SPA";
}
else if (emp_lang.equals("FRE"))
{
header = "FRE";
}
else if (emp_lang.equals("GER"))
{
header = "GER";
}
else
{
header = "ENG";
}
try
{
Ini ini = new Ini(new File("C:/lang.ini"));
L_AMT_REMAIN = ini.get(header, "L_AMT_REMAIN");
L_AMT_TEND = ini.get(header, "L_AMT_TEND");
L_APPROVED = ini.get(header, "L_APPROVED");
L_ARE_YOU_SURE = ini.get(header, "L_ARE_YOU_SURE");
[...]
L_WELCOME = ini.get(header, "L_WELCOME");
L_WELCOME2 = ini.get(header, "L_WELCOME2");
L_XACT_CHNG = ini.get(header, "L_XACT_CHNG");
L_YES = ini.get(header, "L_YES");
System.err.println("Employee Language: " + header);
}
catch (InvalidFileFormatException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
} // end public static void main
That's for the majority of the strings to be displayed in different languages. There is another method inside Lang that loads some other strings, independent of the first set. I don't believe it factors into this problem but I can post it if needed.
The order in which these classes/methods get launched is as follows:
GUI.Main calls the Login class, which calls a CreateLogin method. That method calls Clients.main, which gets the DB_info array from GUI passed to it. Clients fills the DB_info array. Lang.other is then called (to get language-specific strings for the login page), and the Login buttons and labels are created. Once a login is successful, the perferred language of the employee logging in (from a DB) is passed to Lang.main to load the other strings (hence the emp_lang being passed in the code above).
Up until I added the code for the Locale object, all of this worked fine. Now I get the ExceptionInInitializerError exception. Anyone know what's going on?
BTW, for loading from the ini file I'm using ini4j. Some forum posts I found while googling suggest this is a problem with that, but I don't see how it relates to the problem with Locale objects. The ini stuff works (worked) fine.
Sounds like you have a cycle in your static initializers, so something is not initialized yet.
GUI calls Lang's static initializer before getting Lang.L_WELCOME. Lang calls GUIs static initializer in line 2. Your exception trace makes it look like GUI calls Langs static initializer for some reason.
In all, cycles like this mean that someone is going to reference a statically initialized object and get null instead of what they expected to get. In this case, I suspect Lang.java, line 2, is passing two null pointers to the Locale constructor.
As Keith notes, you have a static initializer cycle. To help future readers...
To minimize these bugs, initialize (simple) constants (with no or minimal constructors) before (complex) variables, so here String before Locale – less room for cycles to cause problems.
Debugging-wise, NullPointerException on a static field and 2 <clinit> in stack trace, with the earlier class appearing in the failing line, are the clues that this is an uninitialized field caused by a static initializer cycle.
so suppose I have a java package....
it's got the main class with the main method
and then it's got a whole bunch of other classes.....
my question is, is it possible to get the args that was passed into the main method from these other classes that are not part of the main class but in the same package...
No, not portably, there may be some trickery based on the JVM implementation but I've never seen it, and it would be a very bad idea to rely on it even if it existed.
If you want those values elsewhere, the main function needs to make them available somehow.
An easy way to do this (not necessarily the best way) is to simply store away the strings as the first thing in main and provide a means for getting at them:
Scratch2.java:
public class Scratch2 {
// Arguments and accessor for them.
private static String[] savedArgs;
public static String[] getArgs() {
return savedArgs;
}
public static void main(String[] args) {
// Save them away for later.
savedArgs = args;
// Test that other classes can get them.
CmdLineArgs cla = new CmdLineArgs();
cla.printArgs();
}
}
CmdLineArgs.java:
public class CmdLineArgs {
public void printArgs() {
String[] args = Scratch2.getArgs();
System.out.println ("Arg count is [" + args.length + "]");
for (int i = 0; i < args.length; i++) {
System.out.println ("Arg[" + i + "] is [" + args[i] + "]");
}
}
}
And, when run with the arguments a b c, this outputs:
Arg count is [3]
Arg[0] is [a]
Arg[1] is [b]
Arg[2] is [c]
The system-properties on some (?) JRE-implementations provide the system-property "sun.java.command" to get the programm-name and parameters that were used to start the program. Like "myjar.jar param1 param2 ...".
While this value doesn't even belong to the set of properties that are mentioned in the documentation, it is present in both Oracle-JRE v1.8 and OpenJRE v1.8 (tested).
I couldn't find any documentation whether this value is supported by default though (best I could find was the list in the System#getProperties() docs). Any clarification on this would be welcome. Handle with care!!!
If you don't care about OS portability, read /proc/self/cmdline or the equivalent for your OS.
See http://en.wikipedia.org/wiki/Procfs
As paxdiablo said, your main class would have to store these parameters and then either distribute or make available to needed ones. Often a good idea would be to let another class do the parsing of these parameters, and provide an object of this class instead of the raw command line to whoever needs it.
I'm kind of a newb at this, but you should be able to store the string[] args to a private instance variable, then make an accessor method for it.
E.g.,
public class test {
private String[] myArgs = new String[10];
public static void main(String[] args) {
myArgs = args;
}
public String[] getArgs() {
return myArgs;
}
}
Not sure if it will work, but that's the idea.