Java I/O help. Jar Cannot Open File: URI is Not Hierarchal - maven

I have been searching for 3 days now nonstop looking at every post I can find. My program runs on IntelliJ, but cannot run on an executable. Your help would be appreciated :)
More importantly, where can I find a in depth user-friendly tutorial? Is there a course or book I can pay for? On Udemy, the java classes completely fail to mention I/O such as classpath and URI. TutorialsPoint briefly goes over I/O buts its not indepth. Did I miss something? Is there an easier way to do all this??
Similar posts that have not worked for me:
Java Jar file: use resource errors: URI is not hierarchical
https://stackoverflow.com/a/27149287/155167
I am trying to load an excel file. I am using Maven. Apache POI says it needs a File. So InputStream does not work. http://poi.apache.org/components/spreadsheet/quick-guide.html#FileInputStream
When I java -jar jarFile, it gives me the error:
C:\Users\1010\Documents\Personal\MonsterManager>java -jar monsterManagerVer3.jar
Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierarchical
at java.base/java.io.File.<init>(File.java:421)
at LoadExcel.<init>(LoadExcel.java:62)
at monsterRunner.<init>(monsterRunner.java:13)
at monsterRunner.main(monsterRunner.java:24)
Here is the code
public LoadExcel() throws IOException, URISyntaxException, InvalidFormatException {
mNames = null;
URL ins = this.getClass().getResource("/excel_List.xlsx");
if (ins == null)
throw new FileNotFoundException("The XLSX file didn't exist on the classpath");
ins.toString().replace(" ","%20"); //<-Runs without this part
File file = new File(ins.toURI()); //this is line 62
// File f = new File(getClass().getResource("/MyResource").toExternalForm());
//String path = this.getClass().getClassLoader().getResource("/excel_List.xlsx").toExternalForm();
//File file = new File(path);
OPCPackage pkg = OPCPackage.open(file);
XSSFWorkbook wb = new XSSFWorkbook(pkg);
//FileInputStream fis=new FileInputStream(new File(excelFile));
// XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sheet = wb.getSheetAt(0);
loadExcel(sheet);
cacheNames();
// fis.close();
wb.close();
}
If it helps here is the path to the excel file:
src\main\resources\excel_List.xlsx
UPDATE:
so I took the excel file out of the resources folder
\nameOfMyProgram\excel_List.xlsx
and now I get this error.
I tried several versions of using the classLoader, Class and Thread to solve this error from Different ways of loading a file as an InputStream
but I still cannot get it to compile.
Error and my code

If you have to use File object do not put xls-file into resources directory.
Maven puts all files from resources directory into jar.
Java can not create File object based on file in jar-file.
Put your xls-file somewhere in file system and create File object based on its URL.
Since your xls-file is not a resource do not use getResource.
Its URL is its full filename (with path).

This code below works with jar executable
String path = new File("excel_List.xlsx").getAbsoluteFile().toString();
File file = new File(path);
if(!file.exists()){
JOptionPane.showMessageDialog(null,"File not found!");
System.exit(0);
}
OPCPackage pkg = OPCPackage.open(file);
XSSFWorkbook wb = new XSSFWorkbook(pkg);

Related

Spring cannot find the file via specified path

My files hierarchy:
>resources:
>static:
>css:
>json:
>networks:
>network-list.json
>js:
>img:
I've tried to create a new file via:
File jsonNetworkDetailsFile = new File("/json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("static/json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("../json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("../../json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("/json/networks/network-list.json");
...and some more. None of it works.
I'm still getting the
java.io.FileNotFoundException: the system cannot find the path specified
What's the proper way?
EDIT
Found a solution. Had to include full path to the file like:
File jsonNetworkDetailsFile = new File("src/main/resources/static/json/networks/Turtlecoin/turtlecoin-pools.json");
EDIT2
As TwiN stated - it's impossible to reference a file through File object as soon as the app is packed into .jar. A proper solution would include:
InputStream jsonNetworkDetailsFile = new ClassPathResource("/static/json/networks/network-list.json").getInputStream();
InputStream is = new ClassPathResource("/someFile.txt").getInputStream();
where /someFile.txt is in your resources folder.
As mentioned in the documentation for ClassPathResource:
Supports resolution as java.io.File if the class path resource resides
in the file system, but not for resources in a JAR. Always supports
resolution as URL.
In other words, you'll want to use the getInputStream() method for your case:
InputStream is = new ClassPathResource("/someFile.txt").getInputStream();
try {
String contents = new String(FileCopyUtils.copyToByteArray(is), StandardCharsets.UTF_8);
System.out.println(contents); // do something with the content here
is.close();
} catch (IOException e) {
e.printStackTrace();
}
I'm mentioning this because ClassPathResource also has a getFile() method.
For more details, see reference
Try something like this :
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("classpath:static/json/networks/network-list.json").getFile());
You could also use :
#Value(value = "static/json/networks/network-list.json")
private Resource myFile;
And then :
myFile.getInputStream()
(will only work on a class annoted with #Component, #Service... etc)
you can try this to load files from ressources :
ClassLoader loader = Thread.currentThread().
getContextClassLoader();
InputStream configStream = loader.getResourceAsStream("/static/json/networks/network-list.json");
I think you should give the exact location to File object. Another solution:
File currDir = new File(".");
String path = currDir.getAbsolutePath();
// String path = "C:\\ExternalFiles\\"; // Or you can give staticly
File jsonNetworkDetailsFile = new File(path);
Hope it helps.

Spring Boot load another file from app.properties

I am new to Spring Boot. I have this emailprop.properties in src/main/resource:
//your private key
mail.smtp.dkim.privatekey=classpath:/emailproperties/private.key.der
But I am getting the error as
classpath:\email properties\private.key.der (The filename, directory
name, or volume label syntax is incorrect)
How do I properly load this file?
Update-1
my java code is
dkimSigner = new DKIMSigner(emailProps.getProperty("mail.smtp.dkim.signingdomain"), emailProps.getProperty("mail.smtp.dkim.selector"),
emailProps.getProperty("mail.smtp.dkim.privatekey"));
its working as "D:\\WorkShop\\MyDemoProj\\EmailService\\src\\main\\resources\\private.key.der"Instead of emailProps.getProperty("mail.smtp.dkim.privatekey")
Update-2
i have tried java code is
String data = "";
ClassPathResource cpr = new ClassPathResource("private.key.der");
try {
byte[] bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream());
data = new String(bdata, StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
dkimSigner = new DKIMSigner(emailProps.getProperty("mail.smtp.dkim.signingdomain"), emailProps.getProperty("mail.smtp.dkim.selector"),data);
Error is : java.io.FileNotFoundException: class path resource [classpath:private.key.der] cannot be resolved to URL because it does not exist
Tried Code is :
ClassPathResource resource = new ClassPathResource(emailProps.getProperty("mail.smtp.dkim.privatekey"));
File file = resource.getFile();
String absolutePath = file.getAbsolutePath();
Still same error..
please update the answer..
If you want to load this file runtime then you need to use ResourceLoader please have a look here for the documentation - section 8.4.
Resource resource = resourceLoader.getResource("classpath:/emailproperties/private.key.der");
Now if you want to keep this exact path in properties file you can keep it there and then load it in your Autowired constructor/field like that:
#Value("${mail.smtp.dkim.privatekey}") String pathToPrivateKey
and then pass this to the resource loader.
Full example you can find here. I don't want to copy paste it.
If your file is located here:
"D:\\WorkShop\\MyDemoProj\\EmailService\\src\\main\\resources\\private.key.der"
then it should be:
mail.smtp.dkim.privatekey=classpath:private.key.der
EDIT:
I see now, you are using DKIMSigner, which expects file-path string,
Try changing your code like this:
ClassPathResource resource = new ClassPathResource(emailProps.getProperty("mail.smtp.dkim.privatekey"));
File file = resource.getFile();
String absolutePath = file.getAbsolutePath();
dkimSigner = new DKIMSigner(emailProps.getProperty("mail.smtp.dkim.signingdomain"), emailProps.getProperty("mail.smtp.dkim.selector"),absolutePath
);

cannot load and read from properties file

My grade java project has the following structure.
As you can see the resources folder is in present in the class path.
But when I run the following in a class under java folder
new File("somefile.txt").exists()
I get FileNotFoundException.
Could anyone help me find why I am not able to access this file.
This is in the class path.
You can use.
ClassLoader classLoader = getClass().getClassLoader();
String filePath= classLoader.getResource("filename").getFile();
new File(filePath).exists();
For more info, you can go through this tutorial.
You can resolve your issue like below
Properties prop = new Properties();
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("somefile.txt");
if (inputStream != null) {
prop.load(inputStream);
} else {
throw new FileNotFoundException("Property file '" + fileName + "' not found in the classpath");
}
I found it from the post How to read properties file in Java

Maven java.io.FileNotFoundException

I'm developing a project with Maven. In a class to send e-mails, in run and dev modes, I get the following error: Caused by: java.io.FileNotFoundException: jQuery/images/logo.png (Ficheiro ou directoria inexistente) ==> translation = File or directory not found.
I've tryed lots of paths, like "./jQuery/images/logo.png", "/jQuery/images/logo.png" and others. The full relative path is: "src/main/webapp/jQuery/images/logo.png".
In "target" folder, the path is "project-1.0-SNAPSHOT/jQuery/images/logo.png".
Inside war file, is "jQuery/images/logo.png".
I don't think it's important, but I'm using NetBeans 7.1.1 as IDE.
I found that the absolute path returned in runtime is "/home/user/apache-tomcat-7.0.22/bin/jQuery/images/logo.png"!... It's not the project path!
How can I get a file in webapp folder and descendents from a Java class, in a Maven project?
The code is:
MimeBodyPart attachmentPart = null;
FileDataSource fileDataSource = null;
for (File a : attachments) {
System.out.println(a.getAbsolutePath());
attachmentPart = new MimeBodyPart();
fileDataSource = new FileDataSource(a) {
#Override
public String getContentType() {
return "application/octet-stream";
}
};
attachmentPart.setDataHandler(new DataHandler(fileDataSource));
attachmentPart.setFileName(fileDataSource.getName());
multipart.addBodyPart(attachmentPart);
}
msg.setContent(multipart);
msg.saveChanges();
Transport transport = session.getTransport("smtp");
transport.connect(host, from, "password");
transport.sendMessage(msg, msg.getAllRecipients());
The path .../apache-tomcat-7.0.22/bin/jQuery/... is really odd. bin contains scripts for Tomcat, it should not contain any code nor any resources related to your application. Even if you deploy your app in the context /bin, the resources would end up under `.../apache-tomcat-7.0.22/webapps/bin/...
This looks like a mistake made in an earlier deployment.
Now back to your question. To get the path of resource of your web app, use this code:
String absolutePath = getServletContext().getRealPath("/jQuery/images/logo.png");
(docs)

IsolatedFileStorage XML Reading Crash

Ok so, basically my problem is with reading and XML file from IsolatedFileStorage. I'll go through the process that leads to my error and then I'll list the relevant code and XML file.
On the first execution it recognises that the file does not exist - it therefore creates the file in IsolatedFileStorage
On the second execution it can now see that the file does exist and so it loads the XML file
On the third execution it can see that it exists - but it throws an XML error
I cannot for the life of me find a solution to it (link to other discussion on MSDN here)
So the code for reading/creating the XML file in IsolatedFileStorage is as follows:
try
{
/***********************
* CHECK THE SETTINGS
********************/
if (store.FileExists("AppSettings.xml"))
{
streamSettings = new IsolatedStorageFileStream("AppSettings.xml", System.IO.FileMode.Open, store);
DebugHelp.Text = "AppSettings.xml exists... Loading!";
streamSettings.Seek(0, System.IO.SeekOrigin.Begin);
xmlDoc = XDocument.Load(streamSettings, LoadOptions.None);
}
else
{
streamSettings = new IsolatedStorageFileStream("AppSettings.xml", System.IO.FileMode.Create, store);
DebugHelp.Text = "AppSettings.xml does not exist... Creating!";
xmlDoc = XDocument.Load("AppSettings.xml", LoadOptions.None);
}
if (xmlDoc != null)
xmlDoc.Save(streamSettings);
}
catch (Exception e)
{
DebugHelp.Text = e.ToString();
}
finally
{
streamSettings.Close();
}
And the related XML file is as follows:
<?xml version="1.0" encoding="utf-8" ?>
<Settings>
</Settings>
Extremely advanced I know - however it throws the following error (here) and you can find the full error text at the bottom of the Social.MSDN page.
Please help - I have been looking for a solution (as the one on the social.msdn site didn't work) for about 2 weeks now.
Why don't you try to read file using a simple StreamReader ? Below a part of a method I have created to readfile from store. Have a try, check your content, and then try loading xml from String (XDocument.Parse etc ...)
String fileContent = String.Empty;
using (_store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (_store.FileExists(file))
{
_storeStream = new IsolatedStorageFileStream(file, FileMode.Open, _store);
using (StreamReader sr = new StreamReader(_storeStream))
{
fileContent = sr.ReadToEnd();
}
__storeStream.Close();
return fileContent;
}
else {
return null;
}
}
It looks to me like the problem is in your save method - it looks like you are maybe appending the settings each time you close - to overwrite your existing settings, you need to ensure that you delete your existing file and create a new one.
To help debug this, try using http://wp7explorer.codeplex.com/ - this might help you see the raw file "on disk"
As an aside, for settings in general, do check out the AppSettings that IsolatedStorage provides by default - unless you have complicated needs, then these may suffice on their own.
Your code sample isn't complete so it's hard to say for sure but, rather than just seeking to the start of the file you may find it easier to just delete it if it already exists. You can do this with FileMode.Create. In turn this means you can do away with the need to check for the existing file.
I suspect that the problem is that you are writing a smaller amount of text to the file on subsequent attempts and so leaving part of the original/previous text behind. In turn this creates a file which contains invalid XML.

Resources