Ensuring safe file access in both Windows and Linux - java

My team is doing Java Development on Windows, while our production server is running in Linux. We're using a lot of resource files in our projects, and because Windows and Linux use different file systems, it can happen that a file can be found in our development environment, but not in our production environment, e.g. "path/to/file/Filename.txt" can be found in Windows using the path "path/to/file/filename.txt", but the same path cannot find the desired file in Linux.
I'd like to make it so that anytime the file system is accessed in testing scope, it validates that the path will work in the Linux environment. I've figured out that a good test is to make sure that the absolute path is equal to the canonical path [file.getAbsolutePath().equals(file.getCanonicalPath())], but how can I make sure that this is checked everytime a file is accessed? I've thought about creating a new FileSystemProvider and overriding the default FileSystemProvider, but this is very complicated. Is there an easier way?

Related

Why 2 Path for load Library JNA

Hello This is my code :
if (isWindows()) {
//System.setProperty("jna.library.path", getClass().getResource("/resources/win32-x86").getPath());//netbeans WinOs
System.setProperty("jna.library.path", System.getProperty("user.dir").toString()+File.separator+"Desktop");//compiler WinOs
} else if (isMac()) {
//System.setProperty("jna.library.path", getClass().getResource("/resources").getPath());//netbeans MacOs
System.setProperty("jna.library.path", System.getProperty("user.dir").toString()+File.separator+"Desktop");//compiler MacOs
} else {
System.out.println("Your OS is not support!!");
}
Why I have 2 PATH (don't understand because for add an image i have only one Path) by OS, one for use with IDE and another for use with .JAR ?
I just realized, that when I'm use windows and I run the project (from netbeans) the "Library" load and I get the information, but when I compile and I launch my .jar I get error :
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: %1 is not a valid Win32 application.
My Structure
It is correct?
On mac only work with this command : java -jar "/System/Volumes/Data/Users/hugoclo/NetBeansProjects/Prezauto/dist/Prezauto.jar"since Terminal. If click on jar i have message error : Not Found .....
Sorry about my English,
There can be two reasons for the "why". While Java is cross-platform, JNA (which relies on some native code) must necessarily behave differently on different operating systems. Particularly in the case of loading DLLs (Windows) or dynamic libraries (OSX), you don't want to mix and match. Because it might be possible to have a dll with the same name compiled for different operating systems, JNA's Getting Started page identifies standard locations for these libraries:
Make your target library available to your Java program. There are several ways to do this:
The preferred method is to set the jna.library.path system property to the path to your target library. This property is similar to java.library.path, but only applies to libraries loaded by JNA.
Change the appropriate library access environment variable before launching the VM. This is PATH on Windows, LD_LIBRARY_PATH on Linux, and DYLD_LIBRARY_PATH on OSX.
Make your native library available on your classpath, under the path {OS}-{ARCH}/{LIBRARY}, where {OS}-{ARCH} is JNA's canonical prefix for native libraries (e.g. win32-x86, linux-amd64, or darwin). If the resource is within a jar file it will be automatically extracted when loaded.
In your code, you appear to be trying to do the first option (setting the jna.library.path) to include the user's desktop. That's fine for testing, not good for production, and likely the reason your compiled jar can't find it. Furthermore, by setting this variable, you are overwriting any previous (default) location for it. If you want to go this route, you should copy the saved location and then append your own additional path to it.
However, for code you'll distribute to users, you don't want to have to rely on an absolute file path. It's far better to put the library in a standard relative path location: a resources path (src/main/resources if using Maven) that will be available on your (or any user's) classpath when executing. This seems to align with the commented-out Windows branch of your code, which will look in the win32-x86 subdirectory of your resources folder.
You may have told your IDE to add something to the classpath (so it works there) but if it's not in a standard location, it may fail in a jar.
I'm not sure why the macOS branch of your code does not put the resources in the darwin subdirectory but it probably should.

Java Servlet absolute paths outside webfolder [ Windows & Linux ]

Disclaimer : At the moment, due to lack of a Linux dev/test server, I am currently unable to test this myself. Hence me asking the question here. I will have a Linux box eventually but am currently confined to using Windows.
I am designing a webapp that will run in Tomcat 7 on Windows & Linux.
Supposing on both systems the WAR is deployed in the following locations (respectively)
/opt/Tomcat/webapps/MyApp
C:/opt/Tomcat/webapps/MyApp
The Webapp has a Servlet which needs to process files from the OS file system in the following locations
/work/logs/<logfiles>
C:/work/logs/<logfiles>
On Windows I can specify C:/work/logs and the Servlet knows to pick up this absolute path and it works fine. I suspect because the C: at the start. I know this because I have tested this.
My real question is...
On Linux, in the absence of a drive letter, if I ask it to look in /work/logs will it try to look at a relative path :
/opt/Tomcat/webapps/MyApp/work/logs
or will it look in the file system (/work/logs) as I'd like it to?
I'm asking this now because it will ultimately affect the overall design.
Leading slash in Linux means "absolute path", so you can be sure that if you use path like /work/logs/<something> it will understand it as an absolute path.
BTW if you use the same path in Windows it will work and use current disk, i.e. if tomcat's working directory is on C: it will use C: drive, however if tomcat is running on D: this drive will be used.
I can recommend using CATALINA_HOME environment variable to find a folder in which you place your config. For my projects I have the following structure:
$CATALINA_HOME/appconfig/ <-- config
$CATALINA_HOME/webapps/somewar.war <-- your webapps
Inside appconfig I will place a somewar.properties which functions as the configuration for that server. (I also place log4j.properties, and any special certificates / other things that are specific to the server instance you run on, but I try to keep it to a minimum)
As there will always be a CATALINA_HOME set for your project it is reusable.
inside the somewar.properties I would then list
work.path=/work/logs
Using /work/logs will work on both linux and windows as #AlexR mentions (in his much more to the point answer) but you can get into trouble as on linux you would need root access to be allowed to create the /work folder. It depends on who is managing the server and how strict they are.
I prefer the configuration solution so if you end up working on a machine that won't let you use a certain location, you can switch. Ofcourse you do need to be allowed to write inside CATALINA_HOME ;)

Java program is loading from system32 folder, not from folder, which it is placed

I wrote desktop program in Java on Windows 7 and hanged it on startup by writing to registry the path of jar file (kind of C:\Users\User\Documents\My App.jar) in HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Run branch. When my program loads with Windows, it must load some text file that placed in the same folder as the program:
File f = new File("text.txt"); // without full path to file
if(!f.exists())
JOptionPane.showMessageDialog(null, "File not found: " + f.getAbsolutePath());
but cant do it and I get message: "File not found: C:\Windows\system32\text.txt". It appears as if the program is located in the system32 folder and a text file, respectively, too. What did I do wrong?
My theory: if you installed Java for Windows via the traditional installer, in addition to the place you told it to put it (canonically, JAVA_HOME), the installer drops a java.exe in the system32 directory, so it's likely that when you're starting the JVM on startup, system32 is the working directory and that's where it will look for files with relative path names like the one you've provided.
The easiest solution is to specify the path to the text file absolutely in your code. I would also recommend specifying the full path to java.exe in your registry key (I would guess that right now it's just java.exe with no path) so that you can guarantee which version you're running; if you have multiple versions of Java installed only the most recently one installed will have java.exe in system32 and without a qualifying path I would guess that's the one you're getting since PATH will probably be minimal at that point.
As a closing--unrelated to your problem--point, I hate that Java does this on Windows and wipe that copy of java.exe out immediately, and then set up PATH to make sure the version I want is the one that is executed on demand.
You need to get current working directory and use it as a part of absolute path to a file.
Take a look at this question: Getting the Current Working Directory in Java
The other workaround would be to read this registry key you described and using this information to read a file from desired path - read/write to Windows Registry using Java
The path that you are referring is the working directory, and is not where the application is installed. Like if you put a shorcut to it, you can change the working directory and it will change the result you are getting. But as you put it to startup automatically, probably windows is setting this as the working directory.
Like that:
Use registry to startup a program, and also change the current working directory? 1
You can try to pass the file directory to your app with a command line parameter in the registry.
1 - This probably won't solve the problem for you, don't seems you have one, its just an explanation
I think that #Omaha's answer is describing what is going on (you are launching java.exe from the system32 directory - the JRE installer places a copy of java.exe in system32 to make it easier for users to access).
The actual solution to your situation is to adjust your CurrentVersion\Run registry entry so it specifies a default working folder for the application. Check out: Use registry to startup a program, and also change the current working directory?

Where to put DLL file?

I am calling C++ method using DLL file in my Java project. Right now, I have hard coded the path.
The application will be deployed on many machines and it also run on multiple machine. Where should I put my DLL file so that I can load it and call it on any machine?
I've seen applications that put the DLL into the JAR file. At run-time, they extract the DLL from the JAR into a temporary directory and then access it there.
It's not the most efficient approach but the easiest from a deployment perspective.
You have to make sure your DLL is in the classpath.
One such way to do so is to put the path to the DLL in PATH environment variable.
Other option is to add it to the VM arguments in the variable LD_LIBRARY_PATH, like this:
java -Djava.library.path=/path/to/my/dll -cp /my/classpath/goes/here MainClass
If you are developing a complex application, that has to be stable you have to ensure that the DLL you need is put somewhere, where the OS is going to look for it, probably think of an installer script/program.
C:\WINDOWS\system32 (assuming C is the drive where windows is installed, probably you can get it from registry)
I used to use windows long time ago & not an expert, so I made a google search for you and find the link http://vlaurie.com/computers2/Articles/dll.htm
See the last topic in the link (the one starting with headline Using Regsvr32.exe to Register DLLs)

Can i get the absolute path of just moved file to somewhere in native file system from known folder?

I am recently working on a Java desktop application which needs to track a path of file which has been recently moved to somewhere in native file system from the known source.
For Example : - Let's suppose i have a file A.txt in %TEMP% folder (C:\Users\Admin\AppData\Local\Temp\A.txt). Now Operating system moves that file to, suppose my Desktop. So i suppose to get the path "C:\Users\Admin\Desktop\A.txt".
How can I get the destination path, that's unknown, of recently moved file from known source?
Please Note:
We can search the file name on Native file system but it makes the process slow and time consuming. Is there any fast searching code OR JAR, that would be a open source, available which can make a fast search without consuming time.
Can we some who communicate with Operating system which can either give us the path of recently moved file OR we can access its logs Or etc..etc.
It must work with Linux, MAC and Windows.
So finally we need the absolute path of just moved file to somewhere in native file system from known folder.
You could watch the original location with jnotify.
This library work with linux, windows and OSX. It calls you on the move events.

Categories