I was doing some work for college and my main runs this:
Spreadsheet sheet = new Spreadsheet(0,0);
SpreadsheetManager manager = new SpreadsheetManager(sheet);
/* Read an Import file, if any */
String filename = System.getProperty("import");
if (filename != null)
sheet.parseInputFile(filename, sheet);
Thing is, when I actually try to import a file it doesn't do what is supposed to and the filename is always null, so it never reaches my parseInputFile.
My teachers made a bunch of code for different programming exercises that do similar things available, and I've also looked at projects my colleagues did in previous years, but every single one does what I am doing above.
I have to run my program like this: java -Dimport=A-002-002-M-ok.import calc.textui.Calc otherwise none of the tests given by the teachers will run.
I'm sorry if this is not a useful question, but I've tried looking everywhere. If anyone could explain how the System.getProperty("import") works and why it isn't working in this case, I would be very grateful.
I suggest you take a look at the documentation of System.getProperty().
Basically it retrieves a value from the system, either already present or set by you.
To avoid retrieving null you can use another method signature that specify a default value:
System.getProperty("import", "file.txt");
To set a System property, you can specify it at launch:
java -Dimport="file.txt" your_application
or set it programatically :
System.setProperty("import", "file.txt");
When you run your program with:
java -Dimport=foo
then the method call
System.getProperty("import")
should return "foo".
Is ist possible that you write a tiny example program to convince yourself? Without any SheetManagers and all stuff, just
class ItWorks {
public static void main(String[] args) {
System.out.println(System.getProperty("import"));
}
}
Call it thus
java -Dimport=indeed ItWorks
and report what happens.
That being said: if you want to pass command line arguments, why don't you use the facility for command line arguments? (i.e. the String[] array passed to main?)
You could then call your program like this:
java calc.textui.Calc my-nice-spreadsheet.data
=====================================================
Please write the follwoing in your calc.textui.Calc program immediately after the open brace of your class definition:
public class Calc ..... { // a line like this already exists
// insert next line here
public static String filename = System.getProperty("import");
// rest of your class, as before.
}
Then comment out the getProperty() line in your method that didn't work, but leave the rest including the System.out.println(filename);
Does it change?
Maybe system properties are not the most indicated way to do that (depends on your application).
You could also use command line arguments to pass the file name to your main method:
public class CommandLineExample {
public static void main(String[] args) {
if (args.length < 1) {
System.err.println("usage: CommandLineExample <filename>");
System.exit(1);
}
String filename = args[0];
if (filename !=null && !filename.isEmpty()) {
...
}
}
}
Your program should be called as:
java CommandLineExample theFileName
the string "theFileName" will be passed to the main method in args[0] (any additional words will be passed in subsequent positions of args {args[1], args[2], ...})
EDIT
if the program must be called with
java -Dimport=filename ...
then System.getProperty("import") will return the filename.
Confirm that you are calling the correct program (class name, package, version, last compile was successful, ...) and also check that the property is not mistyped like java -Dinport=A-... or has additional spaces, uppercase letters...
Related
I am working on a Java application that will read a file and then after reading it into memory will do further processing .
The requirement for file reading is that the code should read from 'current working directory'.
I have written a method as follows:
public List<String> processFile(String fileName){
String localPath = FileSystems.getDefault().getPath(".").toAbsolutePath() + fileName;
}
This method converts the file into an ArrayList which it returns.
Then using this arraylist further processing needs to be done.
public boolean workOnFile(){
List<String> records = processFile("abc.txt");
// additional logic
}
I am blocked / stumped on how to Junit the file reading part since the requirement is that the file reading needs to occur from 'working directory' so wherever the user will run the program the input file would be read from working directory.
However in case of Junit my test files would be in '\src\main\resources'
As a result test files would not be read by the 'processFile' method since it looks for files in 'current working directory'
One thought is that I need not Junit the file reading but the entire application does something after the file is read - so do I have some 'testing' provisions where while executing Junit I read file in junit and then have provisions in my class under test to inject my testArrayList ?
#Test
public void doSomeValidation() {
String testFile = "XYZ.txt";
ClassUnderTest fixture = new ClassUnderTest();
List<String> testList = /** read file in Junit from /src/main/resources/ **/
/** inject this testList into ClassUnderTest **/
fixture.setFileContent(testList );
/** then continue testing the actual method that needs to be tested **/
assertNotFalse(fixture.workOnFile());
}
To achieve this I would have to change my actual class that needs to be tested to be able to inject the test file read . Something along these lines :
public class ClassUnderTest(){
public List<String> processFile(String fileName){
String localPath = FileSystems.getDefault().getPath(".").toAbsolutePath() + fileName;
}
/** new method used in junit to inject to **/
public void setFileContent(List<String> input){
this.input = input;
}
/** modify this method first check if injected arraylist not null **/
public boolean workOnFile(){
List<String> records;
if(this.input == null){
/** in actual runs this block will execute **/
this.input = processFile("abc.txt");
}
// additional logic
}
}
Is this the right way ?
I somehow feel I am messing around with code to just make it more testable ?
is this even the right approach ?
A simple solution: change your interfaces to be easy to test.
Meaning:
have one method that puts together a file name "in the local path" (the same way your processFile() method builds that file name
then pass the result of that operation to your processFile() method.
In other words: your code limits that method to always compute the full path itself. Which makes it really hard to control, and thus to test.
Thus: dissect your problem into the smallest pieces that are possible.
Then you only need to test:
that your new method Path getLocalPathFor(String fileName) does what it is supposed to do
and then, that your method processFile(Path absFilePath) does what it needs to do (and now, you can test that method with a path that sits anywhere, not just in the local directory)
My scenario:
I have a Main.java file that simply does System.out.println("Hello").
I run it by first, compiling with javac Main.java and then excecuting the command java Main.
Now what I want is that instead of printing "Hello", it will print whatever the user wants, but I don't want to change the source code whenever I want a different output. So I replaced the System.out.println("Hello") with System.out.println(${MESSAGE}). But this gives error "Cannot resolve symbol MESSAGE".
Ultimately, I want a Main.class file and run with something like java Main -env MESSAGE=whateverIPutHere and it should print out whateverIPutHere.
Is it possible?
You can use system properties
public final class Test {
public static void main(String[] args) {
System.out.println(System.getProperty("port") + " port");
}
}
And then compile and run
javac Test.java
java -Dport=8080 Test
Output is : 8080 port
Now what I want is that instead of printing "Hello", it will print whatever the user wants, but I don't want to change the source code.
Simply not possible without changing code.
System.out.println("Hello")
Prints that string. End of story. And:
System.out.println(${MESSAGE})
is simply not valid Java. If you want to read an environment variable, see here how to do that.
But then: that is really a detour here. You can simply pass arguments on the command line:
java Main "some string" "and another one"
and then retrieve those two strings via the String args[] parameter that your main method receives!
The real answer here: you learn a new language by researching how that language works. You don't assume how syntax might look like, based on experiences from other languages. Meaning: $ENV_VAR is a "shell language" concept. Your idea: "maybe Java has the same" is a very inefficient strategy to go about this.
You can use the input arguments:
public static void main(String[] args) {
System.out.println(args[0]);
}
And then call it like this: java Main whateverIPutHere
Simple as that! args is an array containing all the arguments that you pass in the command line.
In this example, we are printing all the arguments passed from the command-line. For this purpose, we have traversed the array using for loop. The arguments passed in command line is captured by args argument.
class test{
public static void main(String args[]){
for(int i=0;i<args.length;i++)
System.out.println(args[i]);
}
}
compile by > javac test.java
run by > java test sonoo jaiswal 1 3 abc
Output:
sonoo
jaiswal
1
3
abc
You can either read it from args as mentioned above, or, if you know how to add a library to your project, try args4j. You'll get way cleaner code as you can use it to separate commandline argument processing to a dedicated class.
I am quite new to Java so this might be quite simple for others.
I'm making a text summarizer by following a tutorial and I came across a slight problem. When I run my program, it outputs "Usage: java Main input.txt keywords ...". So it follows the code "if(args.length < 1)" to do that. However, how do I change it so it reads the text file and carry on with the program.
generatesummary class works perfectly.
if(args.length < 1){
System.out.println("Usage: java Main input.txt keywords ...");
return;
}
String filePath = args[0];
if(filePath == null){
filePath = "./input.txt";
}
String[] keywords = null;
if(args.length < 2){
keywords = new String[1];
keywords[0] = "";
}
else{
keywords = new String[args.length-1];
for(int i=1; i<args.length; i++){
keywords[i-1] = args[i];
}
}
System.out.print("keywords:\t");
for(String keyword : keywords){
System.out.print(keyword+"\t");
System.out.println();
}
//String[] keywords = null;
Generator generator = new Generator();
generator.loadFile(filePath);
generator.setKeywords(keywords);
generator.generateSignificantSentences();
System.out.println(generator.generateSummary());
generator.generateSummary();
}
}
It is a simple check to see whether the user has given at least one argument when launching the application or not. args.length gives the length of the array that holds the command line arguments. To be able to run it, you need to provide a fileName as an argument - that's what the error is suggesting.
So in a command line you would write something like java Main filename.txt for it to be able to pass the check.
args.length provides the length of the arguments sent to the Java application. If args.length < 1, that means no argument was sent to it.
You need to send in the file name that you want your application to process. If you're running Java from the command line, you can just add the file name to the command, such as "java Main file.txt".
Also note that if you're using an IDE to do your development, such as Eclipse, you'll need to send in the argument (file name) in a way that is particular to that IDE. You should consult the help for that IDE, or post here.
Lastly, you can directly just code in the file name in your program, instead of having to send it in through the command line. Get rid of the if(...) statement checking args.length, and change filePath declaration to:
String filePath = "/path/to/filename.txt";
Good luck and best wishes on your Java learning endeavor!
Your main method is like main(String[] args). Now, when you tried to run that class you typed following command I guess.
java classname
So in this case args will not contain anything. But if you type
java classname fielName
args will contain the file name and it will not go inside of the first if block. Because length og args is 1.
I understand you are executing that code inside a main method. The main method has the next signature:
public static void main(String[] args){
...
}
This method is your applications entry point in java. Watching it's signature you can see that it receives an argument named args that is an array of String's. As the main method is the entry point, this arguments come from the place you are executing the application (terminal, IDE, etc). lenght is and attribute of java arrays, that stores the number of elements that array has. By executing if(args.length < 1) you are checking if you received less than one argument, because the code is expecting a filename as argument. Yo have to execute your code form a terminal as the second line says
System.out.println("Usage: java Main input.txt keywords ...");
For adding arguments in eclipse you have to put them into "Run > Run Configurations...> Arguments". This article explains it perfectly: cs.colostate.edu/helpdocs/eclipseCommLineArgs.html
I need to find out the class name from Java code. For example: The target file is aa.txt, the content of this file is as below:
public class HelloWorld{
public static void main(String []args){
System.out.println("Hello World!!!!");
}
}
I want to find out the class name, in this case is HelloWorld so that I can name the .java file as HelloWorld.java.
My question is how can I get Java class name in PHP or JavaScript?
Add:
I will let users to write very simple Java code in my webpage, and I will save their code in files, run their code and return results for them. But right, there may be more than one class in a file.
In PHP:
$source = preg_replace('/\/\*[\s\S]*\*\/|\/\/.*|"(?:\\\\?.)*?"/', '', $source);
if (preg_match('/\bclass\s+(\w+)/', $source, $matches)) {
$className = $matches[1];
}
It strips comments and strings then pulls out the name of the first declared class. (This doesn't handle Unicode escapes but they're probably a non-issue as they're never practically used outside of strings.)
In my ANJI (http://anji.sourceforge.net/) java project, I have two java file in package com.anji.neat.
One file names evolver.java which needs one program argument. The output champ-id from evolver.java is to be added as args[1] along with the previous argument fed to evolver.java
How can I add this output to Program Arguments without manually adding it? Plus is it possible that I execute these two java files in one run?
I know the question is complex, but someone kindlu help. I am new to java, so do not get things.
I would suggest that you have main method only in one file, lets say in evolver.java. Add a normal method in your second file which takes two arguments, first argument is the command line argument received in evlover.java and second argument is the champ-id. Run your program by calling the main method of evolver.java. Process the command line argument and generate the champ-id. And after that call the method of your second class by passing both the arguments.
It would become something "ugly" like:
public static void main(String[] args) {
if (args.length == 1) {
String extraArg;
...;
args = new Strinng[] { args[0], nextArg };
// main(args); return;
}
...
}