I have a simple parsing program that takes a few files and combines them. It then generates a few output files to the working directory. When I run this program in eclipse it generates all the required output files. However, when I run it using a jar generated in eclipse it only creates two of the three output files. It makes me think something is wrong in how the jar file is generated but can't seem to find any answers to this.
I've tried updating some of the java, it was written using java 5 I believe. I just changed the Vectors to ArrayLists and the FileOutputStream to FileWriter.
I had to download javax.mail to get the required libraries and added those jar files to the java6 library I was using in Eclipse. I've tried deleting the classes and generating new classes. I tried to check the permissions on the jar file to make sure that I had access with it. I guess I am just not sure where to start.
I've also tried packing this as a jar file and not as a runnable jar file because it gave me more options on what to include. However, I could not run this type of jar file even though it was an executable. I've recreated the jar file numerous times without any luck.
There were quite a few problems people had with UTF-8 not displaying properly in a jar file but being fine in eclipse. However their jar files were generating the text files where as mine just does not generate one.
Update: Interestingly if I move the block of code to its own class and run it as a separate jar it will work. So the solution for now is to have two jar files.
This is the code for the ungenerated file:
private static void parseCRNOnly() {
try {
//file to write to
File new_file = new File("CRNOnlyClean.txt");
FileWriter out = new FileWriter(new_file);
//file to read from
File file = new File("CRNOnly.txt");
FileReader reader = new FileReader(file);
BufferedReader buf = new BufferedReader(reader);
try{
String str;
String temp = "\r";
String nl = "\r\n";
String tab = "\t";
str = buf.readLine();
while (str != null && !str.isEmpty()) {
StringTokenizer tokenizer = new StringTokenizer(str," \t");
int column = 0;
while(tokenizer.hasMoreTokens()) {
column++;
temp = tokenizer.nextToken();
if(column == 8){
break;
}
out.write(temp);
out.write(tab);
}
out.write(nl);
str = buf.readLine();
}
out.close();
} catch(IOException e0){
System.out.println("Error Reading From CRNOnly.txt");
JOptionPane.showMessageDialog(null, "Error Reading From CRNOnly.txt");
}
} catch(FileNotFoundException e1){
System.out.println("File CRNOnly.txt Not Found");
JOptionPane.showMessageDialog(null, "File CRNOnly.txt Not Found");
} catch (IOException e) {
System.out.println("Error Reading from FileWriter");
JOptionPane.showMessageDialog(null, "Error Reading from FileWriter");
}
For some reason the jar file was not including some old libraries that I had to add from javax.mail, so I tried making a jar file using netbeans instead and it worked. Netbeans didn't pack the javax.mail libraries into the jar file either but included them in a file with the jar file. Therefore to use the jar file this file must be in the directory as well.
Related
My apologies if this is a duplicate, I've been searching around and haven't found anything that works.
I've been trying export a project as a JAR file that includes reading information from a text file. After doing some research, I changed my reader from FileReader to InputStreamReader, using CLASSNAME.class.getClassLoader().getResourceAsStream("textFile.txt"). (I also understand that it should work without the getClassLoader() method involved) However, getResourceAsStream("textFile.txt") returns null, throwing a NullPointerException when I try to read it using a BufferedReader.
From what I've read, this is because my text file isn't actually in the JAR. Yet when I attempt to do so I still get a NullPointerException. I've also tried adding the folder with the files to the build path, but that doesn't work either. I'm not sure how to check if the files are actually in the JAR and, if not, how to get them in the JAR so they can be found and properly read.
For reference, I currently use Eclipse Neon on a MacBook Air and here is my code that tries, but fails, to read the text file:
public static void addStates(String fileName) {
list.clear();
try {
InputStream in = RepAppor.class.getClassLoader().getResourceAsStream("Populations/" + fileName);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
/*
* NOTE: A Leading slash indicates the absolute root of the directory, which is on my system
* Don't use a leading slash if the root is relative to the directory
*/
String line;
while(!((line = reader.readLine()) == null)) {
list.add(line);
}
reader.close();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "The file, " + fileName + ", could not be read.", "Error", JOptionPane.ERROR_MESSAGE);
} catch (NullPointerException n) {
JOptionPane.showMessageDialog(null, "Could not find " + fileName + ".\nNull Pointer Exception thrown", "Error", JOptionPane.ERROR_MESSAGE);
}
}
Thank you for your consideration and I appreciate and welcome any feedback you might have.
There are a number of ways to check the contents of a .jar file.
Most IDEs have a “Files” section where you can simply expand a .jar file, as if it were a directory.
If your have the JDK’s bin subdirectory in your execution path, you can use the jar command in a terminal:
jar tf /Users/AaronMoriak/repappor.jar
Every .jar file is actually a zip file with a different extension (and one or more Java-specific special entries). So, any command that handles zip files will work on .jar files.
Since you’re on a Mac, you have access to the Unix unzip command. In a terminal, you can simply do this:
unzip -v /Users/AaronMoriak/repappor.jar
(The -v option means “view but don’t extract.”)
If your .jar file has a lot of entries, you can limit the output of the above command:
unzip -v /Users/AaronMoriak/repappor.jar | grep Populations
Your code comment about a leading slash is not quite correct. However, if you remove the getClassLoader() part, the comment is somewhat more correct:
// Change:
// RepAppor.class.getClassLoader().getResourceAsStream
// to just:
// RepAppor.class.getResourceAsStream
// Expects 'Populations' to be in the same directory as the RepAppor class.
InputStream in = RepAppor.class.getResourceAsStream("Populations/" + fileName);
// Expects 'Populations' to be in the root of the classpath.
InputStream in = RepAppor.class.getResourceAsStream("/Populations/" + fileName);
im Working on a project that can compile/run existing java files in PC.
most of code works pretty well, but im having a problem at getting the path of java files.
here are the problematic codes
void uploadJ() {
System.out.print("Insert File name : "); //ex)HelloWorld.java
FileName = sc.next();
}
void Compile(){
String s = null;
File file = new File(FileName);
String path = file.getAbsolutePath();
try {
Process oProcess = new ProcessBuilder("javac", path).start();
BufferedReader stdError = new BufferedReader(
new InputStreamReader(oProcess.getErrorStream()));
while ((s = stdError.readLine()) != null) {
FileWriter fw = new FileWriter(E_file, true);
fw.write(s);
fw.flush();
fw.close();
}
} catch...
}
For instance, when i put HelloWorld.java as a file name,
the absolute path of the HelloWorld.java should be C:\Users\user\eclipse-
workspace\TermProject\src\HelloWorld.java,
but instead, the result is C:\Users\user\eclipse-
workspace\TermProject\HelloWorld.java.
it misses /src/ so it always ends up with javac: file not found error.
When your application has been compiled, there will be no src directory. This working directory could also be set to anything.
You also can't guarantee that the file you are looking for is an actual file, in the context of a jar file, it isn't.
However, you can load files from the classpath. You can make use of Class#getResourceAsStream(String):
Finds a resource with a given name. The rules for searching resources associated with a given class are implemented by the defining class loader of the class.`.
Finding the file can be accomplished by calling this.getClass().getResourceAsStream("/" + FileName), with the / causing the search to occur from the resource root.
To use this with javac, you'll have to create a temporary file and populate it with the data stream you get from getResourceAsStream.
My goal is to use Apache CLI with an executable jar file to read in a text file, perform string manipulations, and then write to a CSV. You would execute the tool in the terminal like this:
$ java -jar my-tool-with-dependencies.jar -i input.txt -o output.csv
I've written tests for this functionality and those tests are passing. The test input text file is located in src/test/resources/. The following test is passing:
#Test
public void testWordockerWriteCsvFileContents() {
// Make sure the csv file contains contents
Wordocker w = new Wordocker();
String intext = "/textformat/example_format.txt";
String outcsv = "/tmp/foo.csv";
w.writeCsvFile(intext, outcsv);
try {
Reader in = new FileReader(outcsv);
Iterable<CSVRecord> records = CSVFormat.DEFAULT.parse(in);
for (CSVRecord record : records) {
assertTrue(record.toString().length() > 0);
}
} catch(FileNotFoundException e){
assertTrue(false);
} catch(IOException e) {
assertTrue(false);
}
File file = new File(outcsv);
if (file.exists()) {
file.delete();
}
}
We I compile my jar files with dependencies using mvn clean compile assembly:single then I raise the following FileNotFoundException:
// Get file from resources folder
URL resourceURL = ParseDoc.class.getClassLoader().getResource(fileName);
if (resourceURL == null) {
throw new FileNotFoundException(fileName + " not found");
}
file = new File(resourceURL.getFile());
This leads me to believe that there is an issue with where ParseDoc.class.getClassLoader().getResource(fileName); is looking for the file. I'm aware of related questions which have been asked. Related questions are the following:
Strange behavior of Class.getResource() and ClassLoader.getResource() in executable jar
What is the difference between Class.getResource() and ClassLoader.getResource()?
MyClass.class.getClassLoader().getResource(“”).getPath() throws NullPointerException
this.getClass().getClassLoader().getResource(“…”) and NullPointerException
getResourceAsStream returns null
None of these questions appear to ask about how to use an executable jar with Apache CLI. I think the basic issue is that the filepath given by my command line argument cannot be found by URL resourceURL = ParseDoc.class.getClassLoader().getResource(fileName);.
Please let me know what you think. Thank you for your time.
I'm posting this as answer as well after discussion via comments:
Classloader.getResource() is only fetching files that are packaged as part of the Jar-file or located in the classpath-folders.
For reading a normal file you would use something like your first example, i.e. FileReader or FileInputStream or simply pass a java.io.File depending on what the library that you are trying to use supports.
I have a java project this project has a text file to read from. i want to export a excuteable jar file .
i did it but when i run the program on cmd window it says that the file couldnt be found.
How to export the whole project inclusive the text file ? or should i place the file in another place
scn = new Scanner(new File("src/test.txt"));
while(scn.hasNext())
{
String instructionLine = scn.next();
li.add(instructionLine) ;
}
scn.close();
}
catch(Exception e)
{
System.out.print("File couldnt found !");
}
You need to use getResourceAsStream() to get data from within your jar file.
See this "prior answer on StackOverflow".
I am making a program that opens and reads a file.
This is my code:
import java.io.*;
public class FileRead{
public static void main(String[] args){
try{
File file = new File("hello.txt");
System.out.println(file.getCanonicalPath());
FileInputStream ft = new FileInputStream(file);
DataInputStream in = new DataInputStream(ft);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strline;
while((strline = br.readLine()) != null){
System.out.println(strline);
}
in.close();
}catch(Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
but when I run, I get this error:
C:\Users\User\Documents\Workspace\FileRead\hello.txt
Error: hello.txt (The system cannot find the file specified)
my FileRead.java and hello.txt where in the same directory that can be found in:
C:\Users\User\Documents\Workspace\FileRead
I'm wondering what I am doing wrong?
Try to list all files' names in the directory by calling:
File file = new File(".");
for(String fileNames : file.list()) System.out.println(fileNames);
and see if you will find your files in the list.
I have copied your code and it runs fine.
I suspect you are simply having some problem in the actual file name of hello.txt, or you are running in a wrong directory. Consider verifying by the method suggested by #Eng.Fouad
You need to give the absolute pathname to where the file exists.
File file = new File("C:\\Users\\User\\Documents\\Workspace\\FileRead\\hello.txt");
In your IDE right click on the file you want to read and choose "copy path"
then paste it into your code.
Note that windows hides the file extension so if you create a text file "myfile.txt" it might be actually saved as "myfile.txt.txt"
Generally, just stating the name of file inside the File constructor means that the file is located in the same directory as the java file. However, when using IDEs like NetBeans and Eclipse i.e. not the case you have to save the file in the project folder directory. So I think checking that will solve your problem.
How are you running the program?
It's not the java file that is being ran but rather the .class file that is created by compiling the java code. You will either need to specify the absolute path like user1420750 says or a relative path to your System.getProperty("user.dir") directory. This should be the working directory or the directory you ran the java command from.
First Create folder same as path which you Specified. after then create File
File dir = new File("C:\\USER\\Semple_file\\");
File file = new File("C:\\USER\\Semple_file\\abc.txt");
if(!file.exists())
{
dir.mkdir();
file.createNewFile();
System.out.println("File,Folder Created.);
}
When you run a jar, your Main class itself becomes args[0] and your filename comes immediately after.
I had the same issue: I could locate my file when provided the absolute path from eclipse (because I was referring to the file as args[0]). Yet when I run the same from jar, it was trying to locate my main class - which is when I got the idea that I should be reading my file from args[1].