I am using the following code to open a pdf file from java. The code works when I run the application from the IDE. However, when generating the jar and executing it, the code stops working. I do not know what I'm doing wrong. I have tried changing the jar of folders but it still does not work. It seems that the problem is how ubuntu 16.04 handles the routes because in windows this works correctly. The application does not throw exceptions
The way I get the pdf I do the same for another application but in it I get an image and it works both in the jar and in executing it in the ide.
jbTree.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/tree.png")));
Button code
if (Desktop.isDesktopSupported()) {
try {
File myFile = new File (getClass().getResource("/help/help.pdf").toURI());
Desktop.getDesktop().open(myFile);
} catch (IOException | URISyntaxException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
}
The solution is run the application through the console. Trying to run it in another way does not work.
When you run the project from your IDE then the root of your project is the System.getProperty("user.dir") e.g if it Your project root folder is PDFJar the it will look for the help.pdf in the PDFJar/src/project/help/ folder.
After building your project to jar file the executable jar is build and executed from a dist or bin folder which is now the System.getProperty("user.dir") and the help.pdf will be seeked in the dist/src/project/help/ folder.
You either create the folder /src/project/help/ with help.pdf in it in your dist or bin directory or put your Jar file in your project root
EDITED
You can't access a resources file packed into your JAR archive as file except as input stream, The reason it works from you IDE is because the file exist in the src folder as the executed directory is your project folder. You will need to create the file outside the JAR achive then read the stream into it so you can call Desktop to open it.
package stackoverflow;
import java.awt.Desktop;
import java.awt.HeadlessException;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
/**
*
* #author thecarisma
*/
public class StackOverflow {
public void openHelpFile() {
OutputStream outputStream = null;
try {
File outFile = new File("./help.pdf");
outFile.createNewFile(); //create the file with zero byte in same folder as your jar file or a folder that exists
InputStream in = getClass().getResourceAsStream("/help/help.pdf");
outputStream = new FileOutputStream(outFile);
int read = 0;
//now we write the stream into our created help file
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
if (outFile.exists()) {
String path= outFile.getAbsolutePath();
JOptionPane.showMessageDialog(null, path);
if (Desktop.isDesktopSupported()) {
JOptionPane.showMessageDialog(null, "Enter");
try {
File myFile = new File (path);
Desktop.getDesktop().open(myFile);
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Exception");
}
}
} else {
JOptionPane.showMessageDialog(null, "Error Occur while reading file");
}
} catch (HeadlessException | IOException ex) {
Logger.getLogger(StackOverflow.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
outputStream.close();
} catch (IOException ex) {
Logger.getLogger(StackOverflow.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
StackOverflow stackOverFlow = new StackOverflow();
stackOverFlow.openHelpFile();
//the bellow example works for file outside the JAR archive
/**
String path= new File("help.pdf").getAbsolutePath();
JOptionPane.showMessageDialog(null, path);
if (Desktop.isDesktopSupported()) {
JOptionPane.showMessageDialog(null, "Enter");
try {
File myFile = new File (path);
Desktop.getDesktop().open(myFile);
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Exception");
}
} **/
}
}
DETAIL
When your resources file is packed into the JAR archive it cannot be accessed as a file except as a stream of file. The location of the file will be absolute in the JAR archive such as the /help/help.file.
If you just want read the content of the resources such as conf, xml, text file or such you can just read it into BufferReader i.e
InputStream in = getClass().getResourceAsStream("/conf/conf.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
else if it a binary file you will need to create a file outside the jar file with 0 byte then read the resources stream from the JAR archive into the created file.
NOTE: You should check if the help file already exist with the same size before reading from the JAR archive to prevent reading multiple time and skip the process to increase you run time. Take note while creating your file as creating a file in a folder that does not exist in JAVA is not possible.
YOU CAN OPEN YOUR .jar FILE WITH AN ARCHIVE MANAGER, TO VIEW IT STRUCTURE
Related
This sample is supposed to locate the copied over .zip file from the build output directory but for some reason it doesn't find that file. I created a resource directory in the root directory and marked it as "Resource Root" and still didn't work. Any help is appreciated. Here is a snippet of the code:
if (install && package == null) {
File file = new File("file.zip");
byte[] bytes = new byte[(int) file.length()];
try {
FileInputStream inputStream = new FileInputStream(file);
inputStream.read(bytes);
inputStream.close();
}
catch (FileNotFoundException ex) {
System.out.println("File Not Found.");
return;
}
catch (IOException ex) {
System.out.println("Error Reading The File.");
ex.printStackTrace();
}
Here is a screenshot of the project structure:
Project Structure
I suppose you mean you've created the file in the /main/resources folder of your project?
If that's so, then you can copy it as such:
public static void main(String[] args) throws IOException {
var path = Main.class.getResourceAsStream("/myfile.txt");
Files.copy(path, Path.of("file.txt"));
}
I have written this program trying to write to a text file,but nothing is happening after executing the program.Can you suggest how to specify filepath? I am using eclipse and have created a file "out.txt" in the same default package where my class is.
import java.io.*;
public class InputOutput {
public static void main(String args[]) throws IOException
{
int i;
//File file=new File("inputd");
//File file0=new File("out");
FileInputStream fin=null;
//FileOutputStream fout=null;
DataOutputStream fout=null;
//copy the file
try
{
//fin=new FileInputStream("input.txt");
fout=new DataOutputStream(new FileOutputStream("out.txt"));
//fout=new FileOutputStream("out.txt");
fout.write(1);
fout.write(100);
fout.write(1000);
}
catch(IOException ioe)
{
System.out.println("I/O Error" + ioe);
}
finally {
if (fout != null) {
fout.close();
}
//fin.close();
}
}
}
The file will be automatically created and will be in your projects root folder.
Also, if you don't see the file in your project in Eclipse, click on your project in the project explorer and press F5 or right click on your project and select refresh.
This is the code
public static void readCharacters() {
try (FileInputStream fi = new FileInputStream("main/characters.dat"); ObjectInputStream os = new ObjectInputStream(fi)) {
characterList = (LinkedList<Character>) os.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
This is the structure:
And this is the Error
java.io.FileNotFoundException: main\characters.dat (The system cannot find the path specified)
What I want is to include the characters.dat file in my jar, and be able to read and write it while the program runs. Is there a different way to write the path? or to put the .dat file in a different position.
Also the writing method:
public static void writeCharacters() {
try (FileOutputStream fs = new FileOutputStream("main/characters.dat"); ObjectOutputStream os = new ObjectOutputStream(fs)) {
System.out.println("Writing Characters...");
os.writeObject(characterList);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
You can't. You can do one or the other. JAR files are not file systems, and their entries are not files. You can read it with an input stream:
InputStream in = this.getClass().getResourceAsStream("/main/characters.dat");
Check it for null before proceeding.
The jar is for read-only resources. You can use it for the initial file, as a kind of template.
Path path = Paths.get(System.getProperty("user.home") + "/myapp/chars.dat");
Files.mkdirs(path.getParentPath());
if (!Files.exists()) {
try (InputStream in =
Controller.class.getResourceAsStream("/main/characters.dat")) {
Files.copy(in, path);
}
}
The above copies the initial.dat resource from the jar to the user's home "myapp" directory, which is a common solution.
System.getProperty("user.dir") would the running directory. One can also take the jar's path:
URL url = Controller.class.getResource("/main/characters.dat");
String s = url.toExternalForm(); // "jar:file:/.... /xxx.jar!/main/characters.dat"
From that you can also construct the jar's directory. Mind to check Windows, Linux, spaces and such.
URL url = Controller.class.getProtectionDomain().getCodeSource().getLocation();
The solution above risks a NullPointerException, and works a bit differenly running inside the IDE or stand-alone.
Important note:
When using getResourceAsStream, you must start your path by slash /, this specifies the root of your jar, .getResourceAsStream("/file.txt");
In my case my file was a function argument, String filename, I had to do it like this:
InputStream in = this.getClass().getResourceAsStream("/" + filename);
String inXSL="src/main/resources/abc.xslt";
Here am trying to get the file from the path name and process it but the file is never getting recognized from the given path(JAVA).FYI,the system is MAC.
The file is located inside src/main/resources inside the project.
Please provide inputs on this.
When your application is packaged and built, your file will be placed within the class path of your jar (or war) along with the other classes. It should be loaded using a resource stream. Here is some sample code that would print the contents of the file by loading it from the classpath.
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
public class Test {
public static void main(String[] args) throws InterruptedException {
byte[] contents = new byte[1024];
InputStream inStream = Test.class.getClassLoader().getResourceAsStream("abc.xslt");
BufferedInputStream bis = new BufferedInputStream(inStream);
int bytesRead=0;
String strFileContents = null;
try {
while( (bytesRead = bis.read(contents)) != -1){
strFileContents = new String(contents, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.print(strFileContents);
}
}
The important line is:
InputStream inStream = Test.class.getClassLoader().getResourceAsStream("abc.xslt");
Depending on your usage, the input stream would be passed into whatever API you are using.
This is my code snippet:
static String filepath = "test.txt";
public static void main(String[] args) throws IOException {
try{
BufferedReader reader = new BufferedReader(new FileReader(filepath));
String l = reader.readLine();
System.out.println(l);
}catch (FileNotFoundException e){
System.out.println(e);
}
catch(IOException e){
System.out.println(e);
}
java.io.FileNotFoundException: test.txt (No such file or directory)
This is the exception I am getting.
What file path should I use? I put the text file in the bin folder.
I am running Eclipse on Ubuntu, it that matters.
If you are running eclipse and have a java project, then just put the file in the project and it will work.
Place the file at the root directory of the project folder. If your project root directory is FileReader, then place the file into it