Packaged Jar unable to read files from mapped network drive (Windows) - java

I have a Spring Boot application which reads files in folders on a mapped network drive, i.e. m:/PRODUCTION
The problem is, when I execute the jar file, my debugging output shows that no files exist in the folder, even though the folder is full of a files.
I have IntelliJ installed on the same machine, and if I run the application from it's source code, it works absolutely fine.
The method I have that reads filename to an array is;
private File[] getFilesInPath(String path) {
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
if (listOfFiles != null) {
Arrays.sort(listOfFiles, Comparator.comparingLong(File::lastModified));
}
return listOfFiles;
}
Then, I call this function from a number of places in the application, here's an example;
public void manuallyProcessAttritionData(List<Line> lines) {
Handler handler = new AttritionHandler().setLines(lines).setService(this);
String pathToProcess = dataFolder + attritionFolder;
log.debug("Processing path: " + pathToProcess);
File[] listOfFiles = getFilesInPath(pathToProcess);
if (listOfFiles != null) {
log.debug("Number of files to process: " + listOfFiles.length);
for (File file : listOfFiles) {
handler.processFile(file);
}
} else {
log.debug("No files to process");
}
}
The output from running the above is;
Processing ATTRITION data...
Processing path: m:/PRODUCTION
No files to process
...Finished processing ATTRITION data
I've confirmed the path is correct, running the following commands from the command line works fine and there are files in the result;
cd m:\PRODUCTION
M:\PRODUCTION>
Does anyone know of a reason why the folder can be read perfectly find from the application running in IntelliJ, but not when packaged as a JAR file?

Looks like your development account Intellij has access to this drive where as the account which started this spring-boot doesn't have access to it.
I would suggest using full path instead of a mapped network path.

There should be no difference in running the code from intelliJ or running it from the built jar. But there may be other factors comming into play. Maybe you run intelliJ with a different user than the jvm that runs the jar? I propose the following steps to resolve the issue:
1. Use the Path Class to avoid platform specific problems (eg. file separators)
Instead of
new File("path/to/my/directory");
you should use
Paths.get("path", "to", "my", "directory").toFile()
or
Paths.get("path/to/my/directory").toFile()
2. Check the file attributes
Use the code below to investigate if the directory exists, if you have the correct permissions etc.
Path directory = Paths.get("e:/TEMP");
System.out.println("Absolute Path of directory: " + directory.toAbsolutePath());
System.out.println("Directory exists: " + directory.toFile().exists());
System.out.println("Directory is a directory: " + directory.toFile().isDirectory());
System.out.println("Directory isReadable: " + directory.toFile().canRead());
System.out.println("Directory isWriteable: " + directory.toFile().canWrite());
this should output something like:
Absolute Path of directory: e:\TEMP
Directory exists: true
Directory is a directory: true
Directory isReadable: true
Directory isWriteable: true

Related

Java - Create a file in the same directory as the .jar if it doesn't already exist

I am stuck at two parts really.
A) I need the program to find the directory of the RUNNING JAR FILE and check if there is a file called "credits.txt" in the same directory.
B) If not, it would create the file in the SAME DIRECTORY.
The main issue is not being able to get the path of my file.
Say the running jar file was in a folder called "Server", the program would save the name "Server" in a string and then check if a file exists in that string. If so, do nothing, otherwise create the file.
#Override
public void onEnable(){
getLogger().info(ChatColor.GREEN + "Credits has been enabled!");
File file = new File("Credits.txt");
//HERE I NEED THE PROGRAM TO CHECK WHAT DIRECTORY THE RUNNING JAR FILE IS FROM
if (file.exists(//IN THE SAME DIRECTORY AS THE RUNNING JAR FILE)){
getLogger().info(ChatColor.DARK_GREEN + "Credits File Exists");
}else{
getLogger().info(ChatColor.DARK_RED + "Credits File Doesn't Exist!");
//HERE IT NEEDS TO CREATE THE FILE IN THE SAME DIRECTORY OF THE JAR FILE "credits.txt"
}
If you're making a Bukkit plugin, you can use getDataFolder() in your main class. Then you can check if it exists and then create it if it doesn't.
public void onEnable(){
getLogger().info(ChatColor.GREEN + "Credits has been enabled!");
File pluginDirectory = getDataFolder(); //getting the data folder
if(!pluginDirectory.exists()){
pluginDirectory.mkdir(); //Creating the plugin data folder if it doesn't exist.
}
File file = new File(pluginDirectory+File.seperator+"Credits.txt"); //Credits.txt inside the plugin directory
if (file.exists()){ //Checking if Credits.txt exists
getLogger().info(ChatColor.DARK_GREEN + "Credits File Exists");
}else{
getLogger().info(ChatColor.DARK_RED + "Credits File Doesn't Exist!");
file.createNewFile(); //You probably need to create it too
}
}
If you want to create it for storing settings, consider using getConfig() instead of creating a file yourself. It's much easier.

Moving file into a different directory

I am trying to move the failed files to different directory.
Currently, everything seems to work fine except that it creates a file(just plan file without extension). I want directory to be created and all the failed files to go into that directory. Here is my code below. what seems to be wrong?
Path source= Paths.get(("C:/Users/aa/Desktop/whatever" + originalfilename));
Path target = Paths.get("C:/Users/aa/Desktop/Directory1 " );
Files.move(source,target, REPLACE_EXISTING, COPY_ATTRIBUTES);
PS: originalfilename(String) are the filenames of the directory. If I execute it, it gives a file Directory1, but it's not a directory folder.
Try this code instead:
File yourFile=new File("D:\\irectory\\Afile.txt");
if(yourFile.renameTo(new File("D:\\irectory\\" + yourFile.getName())))
System.out.println("File moved succesfully bro!");
else
System.out.println("Errors moving the file.");
From the JavaDoc:
Path source = ...
Path newdir = ...
Files.move(source, newdir.resolve(source.getFileName()), REPLACE_EXISTING);
http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#move%28java.nio.file.Path,%20java.nio.file.Path,%20java.nio.file.CopyOption...%29

java jar file reading image file

i have stand alone application, which has one of the module to sent out emails. This application packaged as executable JAR containing all the resource files including images.
I am using spring for sending email, which contains following code for inline:
Spring code is using org.springframework.core.io.FileSystemResource
//IN-LINE ATTCHEMENTS
if (null != msg.getInlineAttachments() && msg.getInlineAttachments().size() > 0) {
for (Map.Entry<String, File> e : msg.getInlineAttachments().entrySet()) {
if (log.isTraceEnabled()) {
log.trace("Conntent-ID:" + e.getKey() + ", Resource:" + e.getValue());
}
try {
helper.addInline(e.getKey(), new FileSystemResource(e.getValue()));
} catch (Exception e1) {
log.error(e1);
}
}
}
File image is passed to above code using following:
ClassPathResource res = new ClassPathResource("./images/" + name);
if (log.isTraceEnabled()) {
log.trace(res.getFile().getAbsolutePath());
}
file = res.getFile();
Note:
Application works fine when executed in development environment in eclipse, because it is exploded format, non-jar.
Exception:
java.io.FileNotFoundException: class path resource [images/app_logo.png]
cannot be resolved to absolute file path because it does not reside in the file system:
jar:file:/C:/TEMP/app-1.0/app-1.0.jar!/images/app_logo.png
You need to handle the image as a Stream instead of a File. Files are concept that are only valid in a filesystem, but you are trying to access something inside of a Jar which isn't a filesystem.
Only option left out is copy image files into temp folder, and reference from there...

Delete files using java

In my java application, I'm using FilenameFilter to get zip files in given directory. My directory structure is looks like below.
D\:\MyFiles\data\dir1
D\:\MyFiles\data\dir2
D\:\MyFiles\data\dir3
D\:\MyFiles\data\dir4
zip files are in dir folders. I'm giving only D\\:\\MyFiles\\data to my program and it find folders start with dir using FilenameFilter and then find files ends with zip on dir folders.
Inside a for loop I'm creating new File objects for each zip files and call delete() to delete them, but they aren't deleted.
I have printed file path using getPath() method; output is looks like below.
D\:\MyFiles\data\dir1\a.zip
D\:\MyFiles\data\dir1\b.zip
D\:\MyFiles\data\dir2\b1.zip
D\:\MyFiles\data\dir3\d.zip
Then I manually created a File object as File f = new File("D/:/MyFiles/data/dir1/a.zip") and try to delete. It succeeded.
How can I delete files? How can I give the correct path?
UPDATES
This is the code what I'm using:
// this contains folders start with 'dir' in 'D:\MyFiles\data\'
Vector<String> dirList = utl.identifyDir(conf);
File dir;
for (int i = 0; i < dirList.size(); i++) {
// in my properties file ITEM_FOLDER is written as ITEM_FOLDER=D\:\\MyFiles\\data
// LOG.fine(conf.readConfig(Configuration.ITEM_FOLDER)); returns D:\MyFiles\data
dir = new File(conf.readConfig(Configuration.ITEM_FOLDER)
+ File.separator + dirList.get(i));
// this contains all the files ends with 'zip' in 'dir' folders in 'D:\MyFiles\data\'
Vector<String> zipFiles = utl.identifyZipFiles(dir);
for (int x = 0; x < zipFiles.size(); x++) {
/* delete */
File sourcePath = new File(
conf.readConfig(Configuration.ITEM_FOLDER)
+ File.separator + dirList.get(i)
+ File.separator + zipFiles.get(x));
boolean sp = sourcePath.delete();
LOG.fine("sourcePath : " + sourcePath.getPath() + " : "
+ sp);
// one of LOG prints is D:\MyFiles\data\dir3\d.zip : false
}
}
After reading your update, I think there are 2 possible things going on here.
You've still got something open in your application. You don't happen to use a FileInputStream or anything?
Another process is keeping the .zip busy. Did you open that file? Try closing the explorer window or something like that.
EDIT: A checklist from an other user:
Check that you've got the path correct, e.g. what does file.exists() return?
Check that you've got permission to delete the file as the user running your application
Check that you haven't got an open handle to the file within your code (e.g. have you just read from it and not closed the input stream?)
Check that you don't have the file opened in a desktop app
When you create a new File-object to test, something is different then when you use getPath. Notice how all the slashes in the pathname are \ instead of /.

Creating temp Folder in java

I need to create a temp folder where I can put some temp files for processing. I am not sure if I would have Read/Write access in the folder where my application jar would be executed.
Is it best to create the temp folder in the System's temp Directory ?
When I use the File tempFolder = File.createTempFile("fooo",""); Where is the folder created ? When I cd into the temp folder in my mac I am not able to see a folder by name fooo.
You are almost done with create tempfolder, see this:
import java.io.File;
import java.io.IOException;
public class TempFolder {
public static void main(String[] args) throws IOException {
File file = File.createTempFile("my_prefix", "");
System.out.println(file.getAbsolutePath() + " isFile: " + file.isFile() + " isDir:" + file.isDirectory());
file.delete();
file.mkdir();
System.out.println(file.getAbsolutePath() + " isFile: " + file.isFile() + " isDir:" + file.isDirectory());
}
}
first createTempFile will make a real file for you, just remove it and make a directory using the same name.
I use osx, too. My result is:
/var/folders/aQ/aQLNlFLOF28xewK2A7i0X++++TM/-Tmp-/my_prefix8720723534029791962 isFile: true isDir:false
/var/folders/aQ/aQLNlFLOF28xewK2A7i0X++++TM/-Tmp-/my_prefix8720723534029791962 isFile: false isDir:true
When you call File tempFolder = File.createTempFile("fooo","") it will return a File object. You can then call
tempFolder.getAbsolutePath();
linked here
and this will give you the location. At a guess I would say it was in /tmp/ which you can get to in from the Finder
choose Go to Folder
from the Go menu type /tmp/
This will take you to folders that are hidden as well.
I know in windows you can type %temp% in the windows explorer address bar to take you to the temp directory. I am not sure if there is anything like this on OSX
You should use File.createTempFile().
Where it gets created depends on your environment. Try printing out the full path of such a file if your are interested.
On my Mac (10.8.2) the system Java created a file in "/var/folders/qj/v2cqt0t91h1b4rzj1s0pc_780000gp/T/" just now.
Try printing out tempFolder.getAbsolutePath(). It should give you the path where this folder is created.

Categories

Resources