I would like to find out the root of the drive that my Java application is running on in Mac. I have it working on Windows with the following code but I don't know how to make it work on OSx too:
// Method to determine and return the drive the application is running on
public static String getDriveRunningOn(){
// Get the root of all the drives attached to the computer
File[] roots = File.listRoots();
// Get the actual location of the application
// Loop through the roots and check if any match the start of the application's running path
for(int i = 0; i < roots.length; i++)
if(getAppPath().startsWith(roots[i].toString())){
String root = roots[i].toString();
//if(root.endsWith(File.separator) && root.length() > 1) root = root.substring(0, root.length() - 1);
return root;
}
// If the above loop doesn't find a match, just treat the folder the application is running in as the drive
return ".";
}
public static String getAppPath(){
try{
String appPath = MyCellRenderer.class.getProtectionDomain().getCodeSource().getLocation().getPath();
appPath = URLDecoder.decode(appPath, "UTF-8");
return new File(appPath).getAbsolutePath();
}catch(Exception e){return "n/a";}
}
So if the app was located in C:\App.exe, getDriveRunningOn() would output C:\ and so on. I need the same to happen on Mac OSX. Thanks in advance
Ok so, it turns out on Mac File.listRoots() only lists /. I'm not sure whether this is because it only sees internal drives as 'roots' or what but that's what it does. Fortunately, in Mac, all drives/volumes attacthed (including USB drives, basically those listed in Computer) appear as folders in the /Volumes directory.
Therefore, I simply added an if statement in my getDriveRunningOn() method that, if on Mac, returns new File("/Volumes").listFiles() to the file array rather than File.listRoots(). Simples :)
Related
My code runs in the simulator, but crashes on Android with a FileNotFoundException as it tries to FileSystemStorage#openOutputStream in an non-existing directory. I create all the needed directories recursively before using
private void ensureParentDirs(String file) {
final int j = file.lastIndexOf("/");
final String s = file.substring(0, j);
if (storage.isDirectory(s)) return;
storage.mkdir(s);
if (storage.isDirectory(s)) return;
ensureParentDirs(s);
storage.mkdir(s);
if (storage.isDirectory(s)) return;
Log.p("Cannot create directory: " + s);
}
which is supposed to work like new File(file).getParentFile().mkdirs(). It might be wrong, but then it shouldn't run in the simulator either, so I'd call it a bug.
I get the message
Cannot create directory:
file:///data/user/0/my.package.name/files//dump/000/abcd
but the parent directory ("000") has been successfully created. Using adb shell, I can create the directory using
mkdir /data/data/my.package.name/files/dump/000/abcd
so I can't see what's wrong. Any idea?
There was (possibly still existent) problem with double slashes. My path was
/dump/000/abcd
and I transformed it via
path -> APP_HOME_PATH + "/" + path
into
file:///data/user/0/my.package.name/files//dump/000/abcd
which failed because of the double slashes, while
dump/000/abcd
transforms into
file:///data/user/0/my.package.name/files/dump/000/abcd
and works correctly.
I'm using GDAL native library (C++ and it is installed in /usr/lib/java/gdal). I found a trick short time ago, to allow Tomcat can load the web application and this library (cannot use System.load() or System.loadLibrary() as all will return error)
Caused by: java.lang.UnsatisfiedLinkError: org.gdal.osr.osrJNI.new_SpatialReference__SWIG_1()J
Then I need to use a trick to add the library path to JVM when application starts:
final Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths");
usrPathsField.setAccessible(true);
// get array of paths
final String[] paths = (String[]) usrPathsField.get(null);
// check if the path to add is already present
for (String path : paths) {
if (path.equals(pathToAdd)) {
return;
}
}
//add the new path
final String[] newPaths = Arrays.copyOf(paths, paths.length + 1);
newPaths[newPaths.length - 1] = pathToAdd;
usrPathsField.set(null, newPaths);
This works well when the Tomcat starts with application, however, if I redeploy the application, it will return error:
Caused by: java.lang.UnsatisfiedLinkError: Native Library /usr/lib/java/gdal/libgdaljni.so already loaded in another classloader
I could not find any solution in StackOverflow, so I ask here if anyone can give some information. I also cannot change or add library path to environment variable or Tomcat folder, all should be done in Java code only.
So to avoid to add library to Tomcat/lib folder, I copy all the GDAL native folder to a temp directory with time stamp (e.g: /tmp/gdal_native/date.time), then I use the code above normally, except when it checks for the previous path, it will override with the new one.
String tmpTargetNativeFolderPath = "/tmp/gdal_native" + "/" + current date time
int i = 0;
// check if the path to add is already present
for (String path : paths) {
String pathFolder = StringUtils.substringBeforeLast(path, "/");
if (pathFolder.equals("/tmp/gdal_native")) {
// Override the old path with the new one
paths[i] = tmpTargetNativeFolderPath;
usrPathsField.set(null, paths);
return;
}
i++;
}
Then Classloader will load the library from another folder when the web application is redeployed without the error and the usrPathsField only contains one folder path to /tmp/gdal_native/timestamp.
I have written method that recursively deletes directory with its contents.
Code is executed on Windows - Eclipse - JVM7
Here's the code:
/**
* Empty and delete a folder with recursion.
*
* #param folder
* folder to empty
*/
public static boolean rmdir(final String folderPath, boolean deleteParent) {
File folder = new File(folderPath);
// check if folder file is a real folder
if (folder.isDirectory()) {
File[] list = folder.listFiles();
if (list != null) {
for (int i = 0; i < list.length; i++) {
File tmpF = list[i];
if (tmpF.isDirectory())
rmdir(tmpF.toString(), true);
tmpF.delete();
}
}
if (deleteParent && !folder.delete()) {
return false;
} else
return true;
}
return false;
}
When the code is executed no error is thrown, saying that directory has been deleted successfully.
When I open drive to confirm deletion, I can still see the folder which is now 0 bytes in size with "Access denied" error when trying to open it.
EDIT:
I am administrator, have all permissions and can R/W to this folder from Windows explorer (before Java breaks it).
My question is has anyone seen this before and what could be the cause of this??
One more thing:
It seems that the directory gets set to "DeleteOnExit" instead of "Delete" right away.
Because when program ends in Lotus Notes or Eclipse directory disappears.
Ok I got this resolved...
I was not Java issue, it was Lotus Notes/Domino issue.
Here comes the long sentence:
It seems when Lotus Notes/Domino thread creates folder "A" and some files in it using LotusScript mkdir, rmdir, and other IO methods and then executes Java VM which tries to delete folder "A" with all files in it, parent thread (Lotus Notes/Domino) gets corrupted and loses directory structure handle which results in error above.
Solution to the problem is simple Dir$() statement after Java finishes folder deletion.
When Dir$() is executed, phantom folder disappears.
Probably because the Dir$() call refreshes and releases whatever should be refreshed and released internally.
Java is probably not the best language to solve this problem in. You can do this with batch file programming in one line: rmdir <directory-to-completely-remove> /s /q. If you absolutely must do this in Java, then you can run this command from a Java program on windows with: Runtime.getRuntime().exec("cmd /C start /min cmd.exe /K \"rmdir <directory-to-remove> /s /q & exit\"");
Developing search utility to search a file entire computer system, works fine on windows platform but becomes an infinite process in ubuntu linux. Please help to overcome this flaw. The following is the main part of the code.
public static void fun(File f){ // root directory is passed as argument
try{
if(f.isDirectory()){
File [] fi=f.listFiles();
for(int i=0;i<fi.length;i++){
if(fileFound==true) break; // fileFound is boolean data type used as flag to indicate whether the file is found or not
System.out.println(fi[i].getName());
fun(fi[i]);
}
}
else{
if(f.getName().equalsIgnoreCase(txtFile.getText()) ||
(f.getName().toLowerCase().startsWith(txtFile.getText().toLowerCase())) ||
(f.getName().toLowerCase().endsWith(txtFile.getText().toLowerCase()))){
l.setText("file found " + f.getAbsolutePath()); // l is JLabel that indicated prints the info like file found and its path
fileFound=true;
}
}
}
catch(Exception e){
}
}
The error you are observing may be due to nested symbolic links.
The most effective approach to solve this problem would be to instead use FileUtils#iterateFiles from the excellent Apache Commons IO library.
There is something like "." (current directory) and ".." (above directory) in each dir in linux. Maybe thats your problem.
In unix like systems the first folder is "." (current folder)
and the second folder is ".." (the root folder)
you should skip the first 2 folders to avoid getting to the same folder over and over again.
try:
if(fi[i].getName() == "." || fi[i].getName() == "..")
continue;
I've been looking to incorporate a Python Script a friend made for me into a Java application that I am trying to develop. After some trial and error I finally found out about 'Jython' and used the PythonInterpreter to try and run the script.
However, upon trying to run it, I am getting an error within the Python Script. This is odd because when I try run the script outside of Java (Eclipse IDE in this case), the script works fine and does exactly what I need it to (extract all the images from the .docx files stored in its same directory).
Can someone help me out here?
Java:
import org.python.core.PyException;
import org.python.util.PythonInterpreter;
public class SPImageExtractor
{
public static void main(String[] args) throws PyException
{
try
{
PythonInterpreter.initialize(System.getProperties(), System.getProperties(), new String[0]);
PythonInterpreter interp = new PythonInterpreter();
interp.execfile("C:/Documents and Settings/user/workspace/Intern Project/Proposals/Converted Proposals/Image-Extractor2.py");
}
catch(Exception e)
{
System.out.println(e.toString());
e.printStackTrace();
}
}
}
Java Error regarding Python Script:
Traceback (most recent call last):
File "C:/Documents and
Settings/user/workspace/Intern
Project/Proposals/Converted
Proposals/Image-Extractor2.py", line
19, in
thisDir,_ = path.split(path.abspath(argv[0]))
IndexError: index out of range: 0
Traceback (most recent call last):
File "C:/Documents and
Settings/user/workspace/Intern
Project/Proposals/Converted
Proposals/Image-Extractor2.py", line
19, in
thisDir,_ = path.split(path.abspath(argv[0]))
IndexError: index out of range: 0
Python:
from os import path, chdir, listdir, mkdir, gcwd
from sys import argv
from zipfile import ZipFile
from time import sleep
#A few notes -
#(1) when I do something like " _,variable = something ", that is because
#the function returns two variables, and I only need one. I don't know if it is a
#common convention to use the '_' symbol as the name for the unused variable, but
#I saw it in some guy's code in the past, and I started using it.
#(2) I use "path.join" because on unix operating systems and windows operating systems
#they use different conventions for paths like '\' vs '/'. path.join works on all operating
#systems for making paths.
#Defines what extensions to look for within the file (you can add more to this)
IMAGE_FILE_EXTENSIONS = ('.bmp', '.gif', '.jpg', '.jpeg', '.png', '.tif', '.tiff')
#Changes to the directory in which this script is contained
thisDir = getcwd()
chdir(thisDir)
#Lists all the files/folders in the directory
fileList = listdir('.')
for file in fileList:
#Checks if the item is a file (opposed to being a folder)
if path.isfile(file):
#Fetches the files extension and checks if it is .docx
_,fileExt = path.splitext(file)
if fileExt == '.docx':
#Creates directory for the images
newDirectory = path.join(thisDir, file + "-Images")
if not path.exists(newDirectory):
mkdir(newDirectory)
currentFile = open(file,"r")
for line in currentFile:
print line
sleep(5)
#Opens the file as if it is a zipfile
#Then lists the contents
try:
zipFileHandle = ZipFile(file)
nameList = zipFileHandle.namelist()
for archivedFile in nameList:
#Checks if the file extension is in the list defined above
#And if it is, it extracts the file
_,archiveExt = path.splitext(archivedFile)
if archiveExt in IMAGE_FILE_EXTENSIONS:
zipFileHandle.extract(archivedFile, newDirectory)
except:
pass
My guess is that you don't get command line arguments if the interpreter is called (well not that surprisingly, where should it get the correct values? [or what would be the correct value?]).
os.getcwd()
Return a string representing the current working directory.
Would return the working dir, but presumably that's not what you want.
Not tested, but I think os.path.dirname(os.path.realpath( __ file__)) should work presumably (Note: remove the space there; I should look at the formatting options in detail some time~)