Java $APP_PACKAGE Pathname Variable Not Working - java

According to the Java Info.plist Key Reference for Mac, you're supposed to be able to use the $APP_PACKAGE variable to be able to access the root directory of a Mac Application bundle. So I figure that I can store a file in the Contents/Resources/ folder and access it by calling
new File("$APP_PACKAGE/Contents/Resources/MyFile.txt")
However, this doesn't seem to work and I simply get a file not found error. Moreover, I've tried the following to see if I could narrow down the problem:
new File("$APP_PACKAGE/Contents").exists() //Returns false
System.out.printline(new File("$APP_PACKAGE").getParent()) //Returns an empty string
I did generate the Mac OS X bundle using Eclipse's Export to Mac OS X application bundle, if that matters. Any help (or a suitable workaround) would be greatly appreciated!

I figured it out! Even though the app had a hard time telling me what the working directory is, I managed to figure out that it is the folder that the application is in. Then I was able to solve it by referring to the app as a directory:
new File("MyApp.app/Contents/Resources/MyFile.txt").exists() //Returns true!!!
I'd also like to add that I found the suggestion on this blog post to add the following to my info.plist file:
<key>WorkingDirectory</key>
<string>$APP_PACKAGE/Contents/Resources</string>
Unfortunately, this doesn't seem to work on Mac OS 10.7.5 and the working directory just gets reset to the folder that the application is in.

If the value is set as as an environment variable, you may use System.getEnv() to first get the actual value of APP_PACKAGE then create the File object using it.
String appPackage = System.getEnv("APP_PACKAGE");
new File(appPackage + "/Contents/Resources/MyFile.txt");
That said, from the reading of your given link I wonder if this variable is just expended while read from the plist file, not in your Java process. If the variable is not actually given as an environment variable to your Java program, you can retrieve your file in the Contents directory easily since as I remember the packaging of an app on Mac should have the following architecture
/Contents
/MacOS
YourBinary
/Resources
YourFile.txt
Depending on the current working directory of your app (I think it should default to /Contents/MacOS) you can retrieve the correct path using ../Resources/YourFile.txt. If you don't know the current working directory you can print the value of new File(".").getAbsolutePath()

Related

Finding the Target of a Link produces NIO Exception but works with ShellFolder under Windows

I am doing a recursive search for different types of files within a folder tree. Upon finding a .csv file during the search, I scan the file with a BufferedReader and put the results in to a database for further operations.
The application works perfectly until it comes to soft- or hard links when the .nio. package utilities are not following the link to the actual .csv file.
The canonical path and the absolute Path are totally equal. Even the file properties in the Explorer show a "link" the searching for attributes in Java delivers a "not Symbolic Link" Result..
Initialization of the main directory with
File rootdir = new File ("..").getCanonicalFile();
had no effect. Using
.toRealPath()
had no effect other than finding the symbolic link files as if they where actual files rather than links, but when it comes to the BufferedReader I get a NullPointerException.
I am developing on Windows 7 however the target environment is Linux, JBoss 7 AppServer running on CentOS.
The only workaround - which does get the actual path to the .csv file that is the target of the link was:
String s = arr[index].getCanonicalPath();
ShellFolder folder = ShellFolder.getShellFolder(new File(s));
System.out.println("FOUND A LINK? " + folder.getFolderType()); //LINK
if (folder.isLink()) {
fileToUse = folder.getLinkLocation(); // yaaay working!!!
}
This is not a proper solution, since the target environment is a server up and running under a Linux distribution not Windows. The test did work under the local Windows machine. Same File-System though.
Does anybody have any clue how to solve that issue?
Here's the Windows Explorer view (sorry it's in German). You can see the created softlinks (if I create them as Hard links via
ln source.csv target.csv
it's the same behaviour.

Java get current file name EXE

This is my first Stackoverflow question.
I searched across Google for getting the current file name in Java. Most of the sources tell users how to find the current file name if the file is a JAR file, but I'm asking for if the current file is an EXE file.
I saw one EXE answer in Get name of running Jar or Exe, but I don't think it worked.
I use the JSmooth EXE wrapper (launch4j somehow didn't work for me), and Java 8. Is there a straightforward solution to my question? Also, it's nice to explain how it works, or provide a link to the Java documentary about it.
EDIT: To clarify, let's say that I made a Java program and used a JAR wrapper, and I named the resulting EXE "test.exe". I want the Java program be able to give me the current directory of "test.exe", including the filename itself (test.exe).
ANOTHER EDIT: Just to clarify more, go onto your desktop, create a text file, and put some text in it. Save it, and change the text file to an EXE file. Then, try to open it. Windows will give an error. Notice how the title of the message dialog is the file path of the opened file. That is the type of output I want.
Thanks.
Per the JSmooth documentation,
JSmooth also makes some special variable accessible for your application.
Form Meaning
${EXECUTABLEPATH} Replaced by the path to the executable binary. For
instance, if the executable binary launched is located
at c:/program files/jsmooth/test.exe, this variable
is replaced with c:/program files/jsmooth
${EXECUTABLENAME} Replaced by the name of the executable binary. For
instance, if the executable binary launched is located
at c:/program files/jsmooth/test.exe, this variable is
replaced with test.exe
You set these in JSmooth under the "Environment Settings" (the last panel), which allows you to map the variable name. So,
MY_EXECUTABLEPATH=${EXECUTABLEPATH}
MY_EXECUTABLENAME=${EXECUTABLENAME}
In your application, you can get those with
String execPath = System.getProperty("MY_EXECUTABLEPATH");
String execName = System.getProperty("MY_EXECUTABLENAME");
public class JavaApplication1 {
public static void main(String[] args) {
System.out.println("Working Directory = " +
System.getProperty("user.dir"));
}
}
This will print a complete absolute path from where your application has initialized. It is used to get only the DIRECTORY.
If you are using a .exe why do you not create a installer? You can use Inno Setup, this way you are able to specify where do you want to store your .exe, and get it from your application just passing your custom directory

Get Android application lib directory

I need to specify the location of some native libraries in my Android application. I was accomplishing this with a hard-coded string:
public static final String DLL_DIR_STR = "/data/data/my.application.package/lib";
but wanted to get the path from Android instead. Following posts like this, I used getDir() to find the lib directory, changing
superCollider = new SCAudio(DLL_DIR_STR);
to
superCollider = new SCAudio(container.$context().getDir("lib", 0).getAbsolutePath());
Oddly, the initial libraries seem to load correctly
Trying to load lib /data/data/my.application.package/lib/libsndfile.so 0x42718d80
Added shared lib /data/data/my.application.package/lib/libsndfile.so 0x42718d80
No JNI_OnLoad found in /data/data/my.application.package/lib/libsndfile.so 0x42718d80, skipping init
Trying to load lib /data/data/my.application.package/lib/libscsynth.so 0x42718d80
Added shared lib /data/data/my.application.package/lib/libscsynth.so 0x42718d80
But when libscsynth tries to load some additional code, it's using the wrong path:
OK, listing opendir(/data/data/my.application.package/app_lib)
Any ideas where the "app_" comes from? I thought I must be using getDir() wrong, but the initial files load fine. Could it be something in the native code? Thanks for your help.
I found the answer, quite by accident, in this post. ApplicationInfo.dataDir holds the location of the data directory, and "lib" is easily navigated to from there:
superCollider = new SCAudio(container.$context().getApplicationInfo().dataDir + "/lib");
Alternatively, nativeLibraryDir takes you directly to the lib directory, but requires API level 9.
Thanks for your help!
getDir will always prepend app_ to the directory name so it is very odd that it is working the first time. I would either just expect the app_ to be there or try using getFilesDir, at least you always know what it will return. Does SuperCollider have a restriction on what the directory name is?
I found another SuperCollider Project that seems to be doing the same thing you did initially with the comment "// TODO: not very extensible,".. I found that funny :)

ImageMagick/IM4J FileNotFoundException

I am trying to use IM4J (a Java wrapper for ImageMagick) to create thumbnails of JPEGs and it is my first experience (ever) with both libraries. Please note that this is a hard requirement handed to me by my tech lead (so please don't suggest to use anything other than an IM4J/ImageMagick) solution - my hands are tied on the technology choice here!
I am getting a FileNotFoundException on the and convert command which tells me I don't have one of these libraries (or both) setup correctly.
On my computer, here is my directory structure:
C:/
myApp/
images/ --> where all of my JPEGs are
thumbnails/ --> where I want ImageMagick to send the converted thumbnails to
imageMagickHome/ --> Where I downloaded the DLL to
ImageMagick-6.7.6-1-Q16-windows-dll.exe
...
In my Java project, I make sure that the IM4J JAR (im4java-1.2.0.jar) is on the classpath at runtime. Although I am required to use the 1.2.0 version of IM4J, I have the liberty to use any version of ImageMagick that I want. I simply chose this version because it seemed like the most current/stable version for my Windows 7 (32-bit) machine. If I should use a different version, please send me a link to it from the ImageMagick downloads page in your answer!
As for ImageMagick, I just downloaded that EXE from here and placed it in the folder mentioned above - I didn't do any installation, wizard, MSI, environment variable configuration, etc.
Then, in my Java code:
// In my driver...
File currentFile = new File("C:/myApp/images/test.jpg"); --> exists and is sitting at this location
File thumbFile = new File("C:/myApp/thumbnails/test-thumb.jpg"); --> doesnt exist yet! (destination file)
Thumbnailer myThumbnailer = new Thumbnailer();
myThumbnailer.generateThumbnail(currentFile, thumbFile);
// Then the Thumbnailer:
public class Thumbnailer
{
// ... omitted for brevity
public void generateThumbnail(File originalFile, File thumbnailFile)
{
// Reads appConfig.xml from classpath, validates it against a schema,
// and reads the contents of an element called <imPath> into this
// method's return value. See below
String imPath = getIMPathFromAppConfigFile();
org.im4java.core.IMOperation op = new Operation();
op.colorspace(this.colorSpace);
op.addImage(originalFile.getAbsolutePath());
op.flatten();
op.addImage(thumbnailFile.getAbsolutePath());
ConvertCmd cmd = new ConvertCmd();
cmd.setSearchPath(imPath);
// This next line is what throws the FileNotFoundException
cmd.run(op);
}
}
The section of my appConfig.xml file that contains the imPath:
<imPath>C:/myApp/imageMagickHome</imPath>
Please note - if this appConfig.xml is not well-formed, our schema validator will catch it. Since we are not getting schema validation errors, we can rule this out as a culprit. However, notice my file path delimiters; they are all forward slashes. I did this because I was told that, on Windows systems, the forward slash is treated the same as a *nix backslash, in reference to file paths. Believe it or not, we are developing on Windows
machines, but deploying to linux servers, so this was my solution (again, not my call!).
IM4J even acknowledges that Windows users can have trouble sometimes and explains in this article that Windows developers might have to set an IM4JAVA_TOOLPATH env var to get this library to work. I tried this suggestion, created a new System-wide environmental variable of the same name and set its value to C:\myApp\imageMagickHome. Still no difference. But notice here I am using backslashes. This is because this env var is local to my machine, whereas the appConfig.xml is a config descriptor that gets deployed to the linux servers.
From what I can tell, the culprit is probably one (or more) of the following:
I didn't "install" the ImageMagick EXE correctly and should have used an installer/MSI; or I need to add some other environmental variables for ImageMagick (not IM4J) itself
Perhaps I still don't have IM4J configured correctly and need to add more environmental variables
Could be the Windows/*nix "/" vs. "" issue from my appConfig.xml file as mentioned above
I'm also perplexed as to why I'm getting a FileNotFoundException on a file named "convert":
java.io.FileNotFoundException: convert
I assume this is a batch/shell file living somewhere inside the IM4J jar (since the only thing I downloaded for ImageMagick was the EXE). However, if I extract the IM4J jar I only see classes inside of it. I see "script generator" classes, so I assume these kick off before my cmd.run(op) call and create the convert file, and maybe that's what I'm missing (perhaps I need to manually kick off one of these generators, like CmdScriptGenerator prior to executing my Thumbnailer methods. . Or, maybe my download is incomplete.
Either way, I'm just not versed enough with either library to know where to start.
Thanks for any help with this.
Run the 'ImageMagick-6.7.6-1-Q16-windows-dll.exe' installer first to install the imagemagick libraries. Then make sure your environment path includes the location of the installed binaries ('convert.exe', 'mogrify.exe', etc)
Make sure u have Set the environment-variable IM4JAVA_TOOLPATH.

Java - Find absolute path of file

I need to find the path to the user's vlc.exe file.
How can I do this?
I read this http://docs.oracle.com/javase/tutorial/essential/io/find.html and tried using code like
PathMatcher match = FileSystems.getDefault().getPathMatcher("glob:vjlc.{exe, jpg, png}");
Path filename = FileSystems.getDefault().getPath("vjlc.exe","");
if(match.matches(filename))
{
System.out.println(filename);
}
and
File fil = new File("vlc.exe");
System.out.println( fil.getAbsolutePath() );
neither of which worked
I believe you are trying to do something that is not quite right.
First, you're assuming that vlc.exe exists on the local machine. But what happens if it doesn't?
Second, what happens if VLC decides at some point (new build comes out, or upgrade) to change the exe file name to vlc2.exe?
To deal with this kind of dependency, I suggest you'll pass the vlc file location as a program argument to the main() method.
This way, you can create a batch file that tries to locate the vlc.exe path, and pass it through to the java program.
Another alternative, is to setup an environment variable, that will be set up during the installation of your java application. The installation can search for vlc.exe path, or have the user to set it up. Once the variable is set, the java program can read it from the system arguments (see this example).
A third way is to have a setting files (*.ini like), that will contain the vlc exe path. You can then have the file modified according to the relevant path, and have the java program read from it (as property file). The file can be auto generated too, during the installation process, or manually edited post installation.
You can use getAbsolutePath() function.
I think you're looking for ways of searching for the vlc.exe executable on the PATH. If so, something like the following should help:
String path = System.getenv("PATH");
String pathSeparator = System.getProperty("path.separator");
for (String pathElement : path.split(pathSeparator)) {
File file = new File(pathElement, "vlc.exe");
if (file.isFile()) {
// vlc.exe exists in this location.
}
}
When a user runs VLC installer to install VLC media player under Windows, the installer creates a Windows registry key entry HKLM\SOFTWARE\VideoLAN\VLC\InstallDir. You can retrieve the path stored in the key using Java as follows:
http://www.davidc.net/programming/java/reading-windows-registry-java-without-jni
read/write to Windows Registry using Java
If the HKLM\SOFTWARE\VideoLAN\VLC\InstallDir key is present, you know VLC is installed. If the user decides to install VLC at a different directory than what is suggested by VLC installer as default, the key will be able to tell you that.
This only works when the user installs VLC through its installer. But, it won't work if the user simply extracts VLC from its zip distribution file since this approach won't touch the Windows registry.

Categories

Resources