Execute Jar file in IDE and get the output (String)? [duplicate] - java

This question already has answers here:
Execute .jar file from a Java program
(10 answers)
Closed 6 years ago.
Is it possible to execute a Jar file on my IDE (IntelliJ) to get the output string for my own purpose on the project that I have?
I know that we can make system calls, but in this case I want to add a Jar file on my project and execute it whenever I want it.
For example: I have a project on IntelliJ, one of my classes (on this project) needs to get the output by running the Jar file (which is on my project).
On my terminal, I would do something like java -jar <jar_file>.jar <file>.asm and this would output a result to my terminal.
And I want to get that output from this command on my Java Class.

Your Jar file returns an output string, so I assume, it's main-method could look like:
public static void main(String[] args) {
System.out.println("output string");
}
And now, if you want to use this "output string" string in your own class, you could do it like this:
public class YourClass {
...
public String getOutputStringFromJar() {
String s = ""; // or = null;
try {
Process p = Runtime.getRuntime().exec("java -jar full/path/to/your/Jar.jar full/path/to/fibonacci.asm");// just like you would do it on your terminal
p.waitFor();
InputStream is = p.getInputStream();
byte b[] = new byte[is.available()];
is.read(b, 0, b.length); // probably try b.length-1 or -2 to remove "new-line(s)"
s = new String(b);
} catch (Exception ex) {
ex.printStackTrace();
}
return s;
}
...
}
Now you have the method, that returns the output string, and you can use it however you want, and you know how to execute a Jar file from your project whenever you want

Your ask is not precise, but if i understand what you're doing, you run the Mars.jar with .asm file in param, and you got an output like in the this link with Fibonacci numbers
and now you want to get the Fibonacci numbers in your program? if that is what you need, i would suggest you to decompile the jar to understand his content
When you do so, you'll see that the main class in the jar is like this
public class Mars {
public static void main(String[] args) {
new mars.MarsLaunch(args);
}
}
so simply when you add the jar to your class path, you need to do somthing like this
public static void main(String[] args) throws FileNotFoundException {
// this will redirect your system output to a file named output.txt
PrintStream out = new PrintStream(new FileOutputStream("output.txt"));
System.setOut(out);
String [] myAsmFile = {"C:/produits/Fibonacci.asm"};
new mars.MarsLaunch(myAsmFile);
// and then you can read the output.txt file
}
hope this help you

Related

Java 8 Streams IO - Tests

I've written a simple class whose reading and writing files by using a single stream.
Now I want to test it by using JUnit test or something like that but I have no clue where to start with this because as u can see this is only one stream and text is immediately printing to a new file.
public class OneStreamIOFile {
public void fileReaderWriter(String fileReadPath, String filePrintName) {
try (Stream<String> streamReader = Files.lines(Paths.get(fileReadPath));
PrintWriter printWriter = new PrintWriter(filePrintName)) {
streamReader
.filter(line -> line.matches("[\\d\\s]+"))
.map(line -> Arrays.stream(line.trim().split("[\\s]+"))
.reduce((a, b) -> a + "+" + b).get() + "="
+ Arrays.stream(line.trim().split("[\\s]+"))
.mapToInt(Integer::valueOf).sum())
.forEachOrdered(printWriter::println);
} catch (IOException e) {
System.out.println("File not found");
e.printStackTrace();
}
}
}
Main class
public class Main {
public static void main(String[] args) {
String filePath = "src/test/java/resources/1000.txt";
String filePrintName = "resultStream.txt";
new OneStreamIOFile().fileReaderWriter(filePath, filePrintName);
}
}
Any idea how to deal with this?
A unit test has to focus on the behavior, not on implementation details.
The way you are using to read from a stream and write to another stream doesn't matter.
Here you have to focus on what you have as input and as ouput of the method under test.
In input, you have String fileReadPath representing the file where you read from and and in output you have String filePrintName, the file created by the method under test.
So to unit test OneStreamIOFile.fileReaderWriter(), create an input test file and create an expected output test file containing what you expect as the input test file is passed to the method.
Of course store them in your test folders.
In your test, pass their String representation to the method under test.
Then, assert that the file created by the method has the same content as the expected output file.
You can check if the file has written by using below code snippet.
public class Sample {
#Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
#Test
public void testFileReaderWriter() throws IOException, InterruptedException {
File file=temporaryFolder.newFile("sample.txt");
Date createdTime=new Date();
OneStreamIOFile options=new OneStreamIOFile();
Thread.sleep(1000);
options.fileReaderWriter(file.getAbsolutePath(),"hellow");
Date modifiedTime=new Date();
Assert.assertTrue(createdTime.getTime()<modifiedTime.getTime());
}
}
You have to give some time after creating the file and if you need to check content you can read files content and assert it.
TemporyFolder is a rule using to handle file operations in Junit.

input from file in java

I am java beginner learner and i am trying to output the data on file which i call a.txt. need help i have no idea y i am getting exception error file not open . i put a.txt in the same directory in which i have main and readfile.
- main path : C:\Users\Navdeep\Desktop\java\assign1\src\assign1
- readfile : C:\Users\Navdeep\Desktop\java\assign1\src\assign1
- a.txt : C:\Users\Navdeep\Desktop\java\assign1\src\assign1
Thanks in advance .
main.java
package assign1;
public class main {
public static void main(String[] args) {
readfile r = new readfile();
r.openFile();
r.readFile();
r.closeFile();
}
}
readile.java
package assign1;
import java.io.*;
import java.util.*;
public class readfile {
private Scanner x;
public void openFile() {
try {
x = new Scanner(new File("a.txt"));
} catch (Exception e) {
System.out.println("file not open \n");
}
}
public void readFile() {
while (x.hasNext()) {
String Agent = x.next();
String request_type = x.next();
String classtype = x.next();
String numberofseat = x.next();
String arrivaltime = x.next();
System.out.printf("%s %s %s %s %s \n", Agent,
request_type, classtype, numberofseat, arrivaltime);
}
}
public void closeFile() {
x.close();
}
}
a.txt
1 r e 1 0
2 r e 1 1
If you use a File with a relative path, it is assumed relative to the "current user directory". What's the "current user directory"? See the doc:
A relative pathname, in contrast, must be interpreted in terms of information taken from some other pathname. By default the classes in the java.io package always resolve relative pathnames against the current user directory. This directory is named by the system property user.dir, and is typically the directory in which the Java virtual machine was invoked.
Also from the doc:
On UNIX systems, a relative pathname is made absolute by resolving it against the current user directory. On Microsoft Windows systems, a relative pathname is made absolute by resolving it against the current directory of the drive named by the pathname, if any; if not, it is resolved against the current user directory.
So one way to get the File to be found using a relative path would be to start the JVM in the directory with the file.
However, this approach can be kind of limiting since it constrains you to always start the JVM in a certain directory.
As an alternative, you might consider using ClassLoader#getResourceAsStream. This allows you to load any resource that is on the JVM's "classpath". The classpath can be configured in a number of different ways, including at launch time using arguments to the JVM. So I would suggest using that, rather than initializing your Scanner with a File. This would look like:
InputStream is = StackOverflow.class.getClassLoader().getResourceAsStream("a.txt");
Scanner scanner = new Scanner(is);
Now, when using getResourceAsStream, you have to make sure that the file referenced is on the classpath of the Java Virtual Machine process which holds your program.
You've said in comments that you're using Eclipse.
In Eclipse, you can set the classpath for an execution by doing the following:
1) After running the program at least once, click on the little dropdown arrow next to the bug or the play sign.
2) Click on "Debug configurations" or "Run Configurations".
3) In the left sidebar, select the run configuration named after the program you're running
4) Click on the "Classpath" tab
5) Click on "User Entries"
6) Click on "Advanced"
7) Select "Add Folders"
8) Select the folder where a.txt resides.
Once you have done this, you can run the program using the run configuration you have just set up, and a.txt will be found.
Basic idea of classpath
The classpath represents the resources that the JVM (Java Virtual Machine) holding your program knows about while it's running. If you are familiar with working from a command line, you can think of it as analogous to your OS's "PATH" environment variable.
You can read about it in depth here.
Instead of putting the file in src folder put the txt file in the project ie outside the src.
Here is one using BufferedReader.
public static void main(String[] args) {
// check for arguments. this expects only one argument #index [0]
if (args.length < 1) {
System.out.println("Please Specify your file");
System.exit(0);
}
// Found atleast one argument
FileReader reader = null;
BufferedReader bufferedReader = null;
// Prefer using a buffered reader depending on size of your file
try {
reader = new FileReader(new File(args[0]));
bufferedReader = new BufferedReader(reader);
StringBuilder content = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null)
content.append(line);
System.out.println(content.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
// dont forget to close your streams
try {
if (bufferedReader != null)
bufferedReader.close();
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Let me know if you have any isues.
Good_luck_programming!

Printing to both the console and to a file

I am running a program with many classes, with one driver to run all these classes. When I run the driver, the output prints on the console just fine, but I also need the exact output from the console to be printed to a file.
However, I can't seem to get the console output to print to a file. I have tried the suggestion here
How to write console output to a txt file
By doing this
import java.io.FileOutputStream;
import java.io.PrintStream;
public class Compiler {
public static void main(String args[]){
try {
Parse parser = new Parse();
SemanticAnalyzer sAnalyzer = new SemanticAnalyzer();
String parserfile= parser.parsefile(args[0]);
sAnalyzer.semanticAnalysis(parserfile);
PrintStream out = new PrintStream(new FileOutputStream("output.txt"));
System.setOut(out);
} catch (Exception e) {
e.printStackTrace();
}
}
}
but the file still comes out blank (perhaps because the print statements are in other files?).
Does anyone have any ideas?
Create a method that you'll use throughout your code when outputting anything that prints to both streams:
private void output(String text, PrintStream ps1, PrintStream ps2) {
ps1.println(text);
ps2.println(text);
}
And call it from within the code:
PrintStream ps = new PrintStream(new FileOutputStream("output.txt"));
output("text1", System.out, ps);
output("text2", System.out, ps);
output("text3", System.out, ps);
ps.close();
I'm sure this will be answered before I finish typing... however what's happening here is you're redirecting the (default) output stream from the console to a file. If you want to print to both locations you would need to have a PrintStream that actually logs to both locations. (Or you can go look up a logging solution--there are several). However, in the interest of being mildly academic about it:
http://docs.oracle.com/javase/7/docs/api/java/io/PrintStream.html
You can implement a PrintStream or OutputStream (probably the better choice) that does this by implementing the interfaces and logging to both the file and console in each case (yikes!).
The easier method, which was explained above by #Voicu but feels a bit misguided is to have a method that replaces System.out(); calls by creating a new method that specifies those streams as part of the output. You could easily create a static method to get around this:
//Redirect via a method
public static PrintStream FILE = new PrintStream(new FileOutputStream("output.txt"));
public static void log(String x)
{
FILE.println(x);
System.out.println(x);
}
Now a terrible, but functional solution, would look something like this:
public static class DualStream extends PrintStream
{
private PrintStream out;
private PrintStream file;
public DualStream(File file, PrintStream out) throws FileNotFoundException
{
super(file);//I'm being SUPER lazy/hacky here
this.out = out;
this.file = new PrintStream(file);
}
//... through all the methods I want to use...
public void println(String x) {
out.println(x);
file.println(x);
}
}
public static void main(String ... args) throws FileNotFoundException
{
DualStream out = new DualStream(new File("output.txt"), System.out);
System.setOut(out);
System.out.println("This is a test");
}
Now this is terrible code, first I'm violating my constructors contract to make this work but it does work. I don't recommend doing this at all, I just wanted to prove it "can be done" if you really need it. The correct approach is to use one of the many loggers out there, or frankly, redirect the output on the command line to where you want it.
What you want in this case is to use the operating system or the server you're running on:
(how to redirect a output of a command to two files)
This does EXACTLY what you want but allows the user to log as needed. If you don't want to log using a logging system (Log4J, Logging package, etc...) then I'd leave it up to your users and just use err/out rather than overthinking it. java -jar myjar.jar > log.txt

ClassNotFoundException issue; linux-related issue(School project)

I'm working on a text editor project right now for my programing class and I'm getting an error I've never seen before when I try to run it. It's a fairly long explanation, but basically, i'm Using an editor class that uses several other classes to create a linked list, store a text file in it, and then allow modification of the file. I'm supposed to run it in a linux environment, and the file in question is supposed to be entered as a 'command-line' argument. However, every time I try running it, I get the following error
Exception in thread "main" java.lang.NoClassDefFoundError: myEditor
Caused by: java.lang.ClassNotFoundException: myEditor
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
Could not find the main class: myEditor. Program will exit.
As for the program itself:
import java.util.Scanner;
import java.util.Iterator;
import java.io.*;
public class myEditor {
public static void saveToFile(String text, String filename) throws IOException{
PrintWriter out = new PrintWriter(new File(filename));
out.println(text);
out.close();
}
public static void main(String args[]) {
boolean quit = false;
try {
if(args.length!=1) {
throw new IllegalArgumentException();
}
String filename = args[0];
Scanner input = new Scanner(new File(filename));
//Add exception
UnorderedList<String> list = new UnorderedList<String>();
while(input.hasNextLine()) {
if(list.head==null) {
list.addToFront(input.nextLine());
}
list.addToRear(input.nextLine());
}
System.out.println(">");
do {
Scanner command = new Scanner(System.in);
String comm = command.next();
String[] comm1 = comm.split(" ");
if(comm1[0].equalsIgnoreCase("I")&&comm1[1].equals("")) {
System.out.println("Type a line of text >");
comm = command.next();
list.addToRear(comm);
}
else if(comm1[0].equalsIgnoreCase("I")&&!comm1[1].equals("")) {
int linNum = Integer.parseInt(comm1[1]);
Iterator<String> itr = list.iterator();
String current = "";
for(int count=0;count<linNum;count++) {
current = itr.next();
}
list.addAfter(comm, current);
}
else if(comm1[0].equalsIgnoreCase("D")&&!comm1[1].equals("")) {
int linNum = Integer.parseInt(comm1[1]);
if(linNum<=list.count&&linNum>0) {
Iterator<String> itr = list.iterator();
String current = "";
for(int count=0;count<linNum;count++) {
current = itr.next();
}
list.remove(current);
}
}
else if(comm1[0].equalsIgnoreCase("L")) {
list.toString();
}
else if(comm1[0].equalsIgnoreCase("E")&&!comm1[1].equals("")) {
saveToFile(list.toString(), filename);
quit = true;
break;
}
}
while(!quit);
}
catch(IllegalArgumentException e) {
System.err.print(e.getMessage());
}
catch(FileNotFoundException e) {
System.err.print(e.getMessage());
}
catch(IOException e) {
System.err.print(e.getMessage());
}
}
}
Obviously, there's a load of other classes I used with this one, but it seems to me the error doesn't lie in them. Does anyone have any experience with this kind of error?
EDIT: I almost forgot to mention, by command line argument, I meant that the file this is supposed to be worked with should already be in the linux directory it was placed it. It should apparently take up args[0]
java.lang.classNotFoundException comes in following cases:
1) When we try to load a class by using Class.forName() method and .class file or binary of class is not available in classpath.
2) When Classloader try to load a class by using findSystemClass () method.
3) While using loadClass() method of class ClassLoader in Java.
So it is clear that jvm not able to find your class. Now question is who will tell the jvm that where to look for a class? answer is -- CLASSPATH environment variable.
because Classpath is a parameter—set either on the command-line, or through an environment variable—that tells the Java Virtual Machine or the Java compiler where to look for user-defined classes and packages.
So you can set the CLASSPATH at run time "java $CLASSPATH:. myEditor" or at environment as always to look for your current directory and it will fix the problem.
On linux variant you can set this at .bashrc file ( if using bash) , can use set command, can set at .bash_profile. On Windows you will find the same at "System-->Properties"
Make sure you have compiled your class by javac
Please execute the command with classpath such as
java $CLASSPATH:. myEditor
The error is saying that it can't find the class myEditor at runtime however was present at compile time. In my tests, when I ran the class and I was missing something it would give me that exact error. Are all your classes in the same place (Or properly organized)? Try looking over all the .class files that you need and make sure they are all there. If you provide some more details of how you're compiling and running this I can edit this answer to give you a better one!

How to run compilr.com java .jar executable on windows when its not just java.lang* package

I'm starting to code in Java in spare work time. Problem is everything is locked down and I'm kinda new to ask IT department to install ide or javac at least to me(im not in IT) so Im using Compilr.com which is quite awesome. Yet I tried to save and run the Hello world code already precoded there:
public class ReadFile
{
public static void main(String args[])
{
System.out.println("Hello World from Compilr!");
System.out.println("Press any key to continue.");
try {
System.in.read();
} catch (Throwable t) {}
}
}
Then open windows cmd and run java -jar HelloWorld.jar Which Works.
Then I tried to build and run this code which throws the typical error that I havent properly setup classpath or some manifest made:
import java.io.*;
public class ReadFile{
public static void main(String[] args){
try {
FileReader input = new FileReader(args[0]);
BufferedReader bufRead = new BufferedReader(input);
String line;
int count = 0;
line = bufRead.readLine();
count++;
// Read through file one line at time. Print line # and line
while (line != null){
System.out.println(count+": "+line);
line = bufRead.readLine();
count++;
}
bufRead.close();
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("Usage: java ReadFile filename\n");
}catch (IOException e){
// If another exception is generated, print a stack trace
e.printStackTrace();
}
}// end main
}
The thing it only generates a jar file so I dont have much of choice for compiling. How do I please make working code with all the available non-core java clasess?
/At home I get error even on the helloworld program: Error:Could not find or load main class Program.
You should be able to install both JDK with Netbeans and Eclipse in a local directory without admin rights. While it will be interesting to find out why compilr.com generated jar does not work for you for any serious work you will need a development environment.

Categories

Resources