Error with .jar file -- attempts to locate file in jar folder - java

Hopefully this will make some sense. I'm new to Java and while I've built .jar artifacts before, I have never had to build a program that takes another file as input. I'm running into a weird problem and I'm not sure how to fix it.
Basically, I have a Main.java class that calls a .txt file and passes it to another class, myClass.java. I generated a .jar file with IntelliJ, which inserted itself inside its own folder.
To make things easier, here is the basic structure of my program.
/src
/com.myProgram
Main.java
input.txt
MyClass.java
/out
/artifacts
/myProgram_jar
myProgram.jar
And here is a basic version of what's in Main.java
myClass mc = new myClass("input.txt");
I tried running the .jar file with the command "java -jar myProgram.jar", and I get the error "The system cannot find the path specified". I ran getCanonicalPath() on input.txt. Apparently my program is looking for input.txt in out/artifacts/myProgram_jar instead of in the src/ folder.
What can I do? Even when I put the full path to force the program to look in the src/ folder, it will still attempt to look in the myProgram_jar folder and throw an error. So I cannot execute the file at all. Any suggestions for solving this error are greatly appreciated!

When you build to jar file, it's not a File anymore. A File is only a physical file on the file ystem.
So have 2 way to fix it:
1. You export the txt file to system as D:/New folder, then you get this file with path of this file.
2. You can try this:
try {
URL url = new URL(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().toString()+your path to file in structre);
InputStream in = url.openStream();
} catch (URISyntaxException ex) {
Logger.getLogger(PrepareGUI.class.getName()).log(Level.SEVERE, null, ex);
}

Related

How to iterate on a folder located outside a .jar file running

I have a problem with my java app architecture. I want to deliver a simple .jar file generated with Spring Boot. I need to iterate over files presents in another folder, after running the .jar.
Here is the hierarchy of my directory:
enter image description here
I launch my .jar with a .bat or sh, with java -jar myApp.jar
I have to iterate on all files that are present in myApp/files
it seems simple but I can't find a way to do this ! I try a lot of things found here but nothing works !
I try this but had a nullPointer...
File jarFile = new File(myMainClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
String jarLocation = jarFile.getPath();
Could you help me please with some try to do !
Thanks !
Edit your .bat file to start into your myApp folder like this
#echo off
#do stuff
cd %myApp_folder%
java -jar myapp.jar
and you can resolve your folders via relative path like this:
File confFolder = new File("conf");
File filesFolder = new File("files");

path of a .txt file in java

I work with NetBeans IDE an I have a .txt file saved in src/myapp folder. If I run from the IDE, this recognise my
File file=new File("src/myapp/mytext.txt");
But if I build the jar file and double click it or launch it from command line I get this error:
java.io.FileNotFoundException: src\myapp\mytext.txt
I could insert absolute path, but how can I run my jar independently by the position of my project in the computer?
You can obtain the file path indepently of its position with the following:
ClassLoader classLoader = getClass().getClassLoader();
String path = classLoader.getResource("mytext.txt").toString();
Java is expecting to find the file relative to your working directory. So by hardcoding the file in src/myapp/mytext.txt you are expecting the user of your application to have the
file under the same folder structure.
If you are expecting the file to be at the same level of your jar file, you can just use ./mytext.txt. Do not put your mytext.txt under the src in your project. That is for sources you want to compile and/or bundle inside your jar file. In NetBeans move it outside the /src folder, that way when you run the program from your IDE or when you run it externally from your Jar file you find the file at the same level.
If you want the user to be able to specify the location himself of the file, you can also read the command line arguments (the arguments to your public static void main(String[] args)).
there is no such problem
File file=new File("./src/myapp/mytext.txt");

Can we use windows bat file in Java jar file, so that java can run some windows command, if yes where we should keep bat file in side that jar file

I am trying to execute a windows command inside java code using Runtime.exec() command. It is working fine when put all the necessary batch file and properties file on the root directory. But when i am exporting this is as jar, the java program is throwing error, which is becuase it is not able to find all those dependent .bat and .properties files. Can some one please tell me, where should i keep all the .bat and .properties files in side the folder. Thanks in Advance.
You can do so
Something like
Runtime.getRuntime().exec("cmd /c start yourFile.bat");
You should be able to keep it in the root of your jar if you want
EDIT :
On second thought I don't think you can run bat files inside a JAR
you would have to extract it and then run it
Please give more information on what it is you want the bat file to be doing and I can update this answer maybe there is another way?
Your problem can be divided into two parts: get the bat from the jarand run it.
To get the bat from the jar, you will have to use the ClassLoader to get a resource. you can achieve this by using the method Class.getResource to get the URL or Class.getResourceAsStream to get an InputStream
Anyway, i dont' think you can run the bat from inside the jar. If you try and fail, my advice is to create a temp file, copy your bat into your temp file and run that file.
P.S: Class.getResource finds file in the classpath. If your file is not in your classpath, you won't be able to find it this way.
EDIT: i add the code i'm using to get resources from a general relative path, given the path exist both starting from you working directory and from the home of your jar. It works, i've been able to just pack every folder i need into the jar and ship the jar to another compute rwhere eveything worked fine.
public static URL getResource(String name) {
if ("jar".equals(Main.class.getResource("Main.class").getProtocol())) {
return Main.class.getResource(("\\" + name).replace('\\', '/'));
} else {
try {
return (new File(System.getProperty("user.dir") + "\\" + name)).toURI().toURL();
} catch (MalformedURLException ex) {
return null;
}
}
}
Main is a known class, in this case the class where this static method is. I first use it to get a known url, and see if i am executing from a jar. If i am, i use the getResource, otherwise i use the File api.
the structure i use is this
main_folder\
res\
src\
package\
and, in the jar
file.jar\
package\
res\
and i need to use both File api and getResource since in the rist case the res folder is not in my classpath. with a different structure probably only the getResource method is fine.
This should solve your problem of getting the bat file, you still need to see if you are able to run it, and if you are not, copy everything into a temp file and run the temp file instead.

Reading a file into compiled jar by relative path

How would you read a file into a program that's compiled into a jar next to it through its local directory? The type read would be a simple .txt file.
It depends on what the usage of the program is. Do you know how the jar is supposed to be executed? When you try to run it, does it spit out a "usage: somejar firstarg secondarg" type message?
Also, if its a jar that you've compiled and you know how it should be executed, then you may have forgot to set its main class or manifest.
Check this: http://www.mkyong.com/java/how-to-make-an-executable-jar-file/
If you want to read a file that exists within an external .jar file, you will need to unzip the .jar file first in your code and then retrieve the file. You can do this using Java's zip APIs. See this answer if this is the case: Easiest way to unpack a jar in java
If you want to read a file that is in the same .jar file that your code is executing, you can get the file as a resource. See this answer: Get a resource using getResource()
If the file is simply in the exact same directory as the executable .jar, create a new file like so:
File input = new File("myfile.txt");

Creating a .jar file - Get "Could not find main class" even with manifest.txt WITH a carriage return

I'm trying to create my first jar file and I'm having trouble. I'm using the DOS to do it and my path and everything are all set up correctly.
These are the files I'm trying to include:
Bot.class
Start.class
Stop.class
Thread.class
I've created a manifest file that looks like this (it also has a carriage return at the end)
Main-Class: Bot
Here is what I'm running through the DOS
jar cf Bot.jar Manifest.txt Bot.class Start.class Stop.class Visit.class
It creates the jar successfully and but when I try and execute it, either by clicking on it or using the command prompt I get
Could not find the main class: Bot. Program will exit.
I have tried using both Bot and Bot.class in the manifest file but still get the same error. I've only tried changing the extension on the manifest file to .mf instead of .txt
Thanks in advance for your help!
jar cmf Manifest.txt Bot.jar Bot.class Start.class Stop.class Visit.class
The m switch is needed to tell jar which file is the manifest. Note that the order of m and f must match the order of Manifest.txt and bot.jar
Remember that the directory structure in the jar must match your package structure.
e.g. for package com.me.Bot the added file should be com/me/Bot.class not just Bot.class
learning how to manually build a jar is a fun thing to do once. for the long term, however, i'd recommend learning a build tool (ant, maven, whatever).

Categories

Resources