Different output from getClass().getResource().getPath() depending on environment - java

I'm writing an app in Java in Eclipse where I need to get the absolute path to an image I'm using. I decided to use getClass().getResource().getPath(), and it works great when I'm running the app from Eclipse.
When I export the app to a JAR file, however, the image doesn't appear. I put in a print statement to find out what was coming from the call above, and it turns out that in Eclipse it comes back with something like "/some/path/to/image.jpg" and when I run it from the JAR, it comes back with "file:/some/path/to/image.jpg". I know the extra "file:" is what is causing the problem, but if I'm using getPath(), it shouldn't be there. Even weirder is why does it show up from the JAR but not in Eclipse?

What do you need the path for? To construct a FileInputStream with? If all what you want to do is to get an InputStream of the image, then just use Class#getResourceAsStream() instead.

Related

get the root directory of a maven application

I need to provide a settings file for my program, to which the user should have access to write some of the settings i need.
I created a file under a new directory (called settings) on the root of my application, but i have problem finding it at run time.
I use
File SettingsFile=new File(ClassLoader.getSystemClassLoader().getResource(".").getPath()+"settings/CreateSettings.txt");
When i execute this under eclipse i get
/application/home/dir/target/classes/settings/ZipCreateSettings.txt which is wrong.
If i execute it on terminal using java -jar, i get the correct path,
/application/home/dir/settings/ZipCreateSettings.txt
This would cause me problems cos i need to run the application directly from eclipse and not use the terminal, even though it is going to be executed using the jar when it is up and running.
I cant keep it like that anyway, cos this code might end up in someone else's hands, and they would have no idea what to do with it.
I have also used some other techniques like
new java.io.File("").getAbsolutePath(); but this always gives me the current working directory, so if i execute the jar from /home, i would get /home.
I think the problem might be maven (which i am not familiar with at all) since my code worked with a plain java application some time ago.
Since your file will be located outside your classpath, it is basically outside your application. Your application is not aware of files existing outside it's classpath. So you will need some kind of way to provide the Full/Absolute path to your file. You can't use the classloader in your case.
I suggest you use a system param instead of a hardcoded value. See here

Packaging external files with JavaFX deployment

I have a JavaFX app that reads in a configuration file. I'd like the config file to remain outside of the jar to facilitate modification without recompiling. Is there a way to set up netbeans to grab the config file and include it in the installer?
I've found the option to change to icon and that works fine but I haven't been able to discover how to tell it to also include specific external resources.
I've read the information posted here: http://docs.oracle.com/javafx/2/deployment/self-contained-packaging.htm but I'm still not seeing a way to accomplish this.
I don't think there's a way to do this (though I may be wrong). I needed something similar to this once, and the approach I took was
Package the file in the jar file
At program start-up time, check to see if the file exists in the expected location on the local drive
If it's there, read it, etc
Otherwise, read the contents from the jar and write them to the expected file
This solves the problem of "deploying outside the jar", and it also solves the problem of the user inadvertently deleting the file after deployment, etc.
The way I solved this issue (due to having many dependent .dll's and other type items) was to use netbeans to compile the jar, which has things like images/css/fxml etc. etc. and then use an Inno Script to actually compile and configure the installer, since inno makes it pretty straightforward to include extra resources. I have yet to find a way to do this properly within javafx itself.

Having trouble combining an API .JAR into my .JAR app. JAR within a JAR

Disclaimer:
Before I get the standard "this has been asked 1000 times", let me say that yes, I know. I have read and read and read. Looked at JarJar and One-JAR but the problem is: I am self-taught with only a couple of months of experience under me and I am not familiar with Ant or Maven or anything other than vanilla Java. I use NetBeans as my compiler, just to add.
I have written an application for use at my job. It is just a small app that takes certain input and writes it to an Excel file. I downloaded jexcelapi (jxl.jar) and placed that appropriately. I have no trouble running the file inside of NetBeans or from within the dist/ folder after it is built. Therein lies the problem: if I move the app to, say, the Desktop, I get an error from the JVM saying "A Java Exception has occurred." I know that this is due to the fact that the main class is added to the .JAR automatically but to add another lib, I will have to make a "Class-path" statement within my Manifest. I tried that unsuccessfully. I have tried moving the actual jxl.jar file to my jdk folder and I tried calling the entire file path that points directly to the jxl.jar file into my Manifest. The closest I can get is building the .JAR in NetBeans and it adds the lib folder to the dist folder where the app .JAR is.
I want to distribute this app as just a single .JAR without having to send all the users a copy of the jexcelapi lib. It doesn't have to be a .JAR within a .JAR; it can be whatever way is easiest and simplest. As stated before, I am not familiar with Ant and One-Jar draws on that. I am still learning; can someone point me in the right direction with this? Thank you!
There is a better one for novice programmers.
Launch4j gives what you need, even wraps it to exe file. Yu don't need to know programming at all to use this.
OFC there are ANT task if you ant to automatise the Launch4j , but for that you must leant a bit about ANT :)
After hours of exhausting search, I found something that was incredibly short, sweet, and right to the point. You cannot mess it up. Here is the link.

Strange FileNotFoundException with Image

So I make a couple of images for my eclipse view plugin. Works perfectly. I wake up the next day and the program now tells me that it can no longer find those files. The files are definitely still in the same place I left them, and I haven't touched the code in 24 hrs. I've been messing with this for an hr now and I don't even know where the start debugging this, as my program was fine yesterday.
Sample.gif is in the "icons" folder of my plugin. I've tried moving it to the src folder, and that doesn't work either.
Error message:
org.eclipse.swt.SWTException: i/o error (java.io.FileNotFoundException: sample.gif (No such file or directory))
Code (when I remove this line and all lines of code that use testImage, the plugin runs again):
Image testImage = new Image(null, "sample.gif");
Anyone have any idea what could possibly be causing this, or what information i can provide for someone to give me a direction as to how to debug?
The problem is most likely to do with where the current directory is. When you use a pathname like "sample.gif", the normal behaviour when opening the file is to look in the current directory. If you run the application with a different current directory, the application will look for the file in a different place.
I'm however confused by the current directory concept
Here are some pages that describe the concept:
http://en.wikipedia.org/wiki/Working_directory
http://www.linfo.org/current_directory.html
where should the pictures go?
If you are only ever going to run your application from within eclipse, then you can put them anywhere ... and make sure that your application's Eclipse launcher configuration sets the current directory to a consistent place. (Your current problem is most likely due to the application launcher using the parent Eclipse's current directory, and THAT may depend on where you were when you launched Eclipse ... see linked pages above.)
If you are going to export the built application in some form so that users can use it outside of Eclipse, then the answer depends on the nature of the application and how it will be installed on the user's computer. (On possible solution is to put the images into the application's JAR file, and locate them via the classpath using the ClassLoader.getResource methods.)

Java: Copying an exe-file and launching afterwards fails

I want to copy an existing .exe-file from one directory to another and launch it afterwards with Java. Like this:
FileIO.copy( new File( sourceFile ), new File( targetFile ) );
System.out.println( "Existing: " + new File( targetFile ).exists() );
System.out.println( "Launching " + targetFile );
String cmd[] = { targetFile };
Process p = Runtime.getRuntime().exec( cmd );
p.waitFor();
System.out.println( "Result: " + p.exitValue() );
The output is like this:
Existing: true
Launching C:\test\Launcher.new.exe
Result: 2
So Java says that the file is valid and existing, but Windows just can't launch the process because it thinks the file is not there. The pathes are absolute and with backslashes. I also have all permissions on the files so I'm allowed to execute them.
The Launcher.new.exe is generated by Launch4j, so it's more or less standalone. At least it doesn't depend on DLLs in the same folder. But strange: It works when I copy and launch the notepad.exe.
One more strange thing: If I don't copy the file by Java but by hand, the launching also fails with the same error.
OS is Vista with SP1.
Any clue?
Hmm... I wonder if this might be Vista's wonderful User Access Controls at play...
Are you working within Program Files? If so, move everything out into a seperate folder (c:\CopyTest) and try again - see if that helps...
Without more details, it's hard to give specific answer. Check your permissions on the c:\test directory and the permissions on target file you are trying to execute.
If your path contains forward slashes, you might want to try changing them to backslashes before execing. Also, you should try to make the path absolute, including a drive letter and colon (e.g. C:\test\myprog.exe). Note that if you code the path in a Java String, you need to double up the backslashes...
Once you get that working, you can ease up on those constraints until you figure out what broke your attempt.
EDIT 1: Some common pitfalls with exec() are mentioned in this article. I don't think any of these apply, but you may want to use the coding from the last example to run your .EXE within CMD.EXE to get decent path resolution, error handling and such.
EDIT 2: Your executable file name needs to be interpreted as a long file name. I'm not positive the API can/will handle this. Please try giving the .EXE a short, simple name (just for testing) like NEWPROG.EXE (with no second dot in the name, either!) But first definitely give it a try with CMD.EXE first.
EDIT 3: From reading comments to the other answer: Is it possible your program is indeed running, and itself returning a status of 2 because it is failing to find a file? Is there some way to verify operation of your program, perhaps by calling it from a .CMD batch script that you run from your Java program, and having it write output redirected to a file?
Maybe the problem you might me facing is not having the bundled more in the directory. Launch4j may convert your program to exe, but there just be a local directory to the jre. That folder contains the bin and lib files of any existing Java jre.
Maybe it helps...
Update
Seems like some people are having a tough time understanding what I said. No problem, I'll explain.
Let's take an example that I have created a simple Client Chat App in Java and I exported it into a runnable .../ClientChatApp.jar file. Yet, it still doesn't have the dependencies within it to run the file and needs the installation of Java in the desktop for doing so. For example here, .../ClientChatApp.jar still needs the dependencies of javax.swing.*, java.net.* and java.io.*. Hence it will locate those dependencies from the JDK/JRE it is supposed to use.
Now, when it comes to converting from .../ClientChatApp.jar to .../ClientChatApp.exe, it will work as expected, only if the desktop has Java installed, so that it can collect the dependencies from there. This is not user friendly since any user who doesn't have Java installed will have to install it first to be able to use your app.
Here's where Launch4j helps. When you are converting from jar to exe using this program, then it helps to redirect where the exe will look for the dependencies in a local folder, usually being .../jre/... in the sam directory as the .../ClientChatApp.exe file. Quick tip: To actually do that, go to the same directory as where you want to have the exe file, create a folder there called jre. Now go to C:/Program Files/Java/<<your JDK or JRE folder>>/ and then select and copy the bin and lib folders and copy them. Then go to the directory where you created the folder of jre and paste both of the folders in the folder.
Many users may have already done it, but why I explained all the above is to give a clear understanding of what the jre folder does and hence come to the main point, that you will have to also send the jre folder with the exe file to the user, otherwise there is a point of failure while execution.
You can send them into a .zip file or create an installer exe using Inno Setup. I recommend doing more research if you're wanting to use Inno Setup.
That's it. Thank You! (plz upvote me, its my first answer)

Categories