I am writing a java application which iterates over all the files in a network share and searches the files for some keywords.
I am aware I can use the smbj library, but I want to use native windows/linux mounting.
I am using the net use command on windows and mount -t command on linux.
Is there any difference in mapping the drive to a drive letter?
(So that I can avoid the code to wait if no drive letter is available)
Obviously, I don't need the drive letter for the user, I am unmounting the drive at the end of my code.
Does mapping the drive make further calls to the drive faster?
(X:/Folder vs \Share\Folder)
Related
My Environment is OSX BIG SUR.
For space reasons, I need to move files from my Hard disk to a NAS (on my local network).
The current applications accessing these files (en read mode) were developed in Java.
I suppose I should use a Mount command in programs with the SMB protocol, but how to do this without be prompted for password with the SUDO command ?
So I'm looking for some examples.
You have a few ways to go:
Have java execute the smb mount command
This is a walking disaster; you don't want your java process to gain root privileges to do this.
Have java be an smb client
Possible... use JCifs-ng. The docs are lacking, and this would have been a lot simpler if it had integrated into the new files / filesystem API, but it doesn't. You'll have some coding to do.
Learn sysops
All you really need is for the OS to have that samba share mounted someplace and then, to your java process, it's all just files on a filesystem. Don't make the smb mount happen in java, ensure it's already set up before your java process even starts.
I'm developing a Java software that reads lots of possibly big files.
I'll try to parallelize it, so it reads in parallel files from different devices (HDD, SSD, flash drive, SMB, etc) and only 1 file at a time from each device. But for that I'd need to know in which device a given file is.
On Windows I guess I could just use substring its path for the drive letter, but for Linux I have no idea how that could be done. Is there a standardized way to do it?
The sun.nio.fs.UnixFileAttributes class, which is used for PosixFileAttributes, contains a st_dev field. Unfortunately, it is not public accessible, you might have to use reflection to get the value.
A different approach would be to call stat on the file and read the device id that way. Then you can use the device id to find out which device the file is on.
Also you might want to check the output of mount to check the paths you are using and where they are mounted on.
An executable jar is distributed to users per network drive. I want to prevent users from running it directly on the network because it causes performance and other problems.
One solution can be to check the execution path and compare it with the network drive path, but what if the network drive path is not known in advance? Is there any other possibility?
I don't think you can do this in pure Java. I'm pretty sure you will need to either run an external command or make a call into native code to detect the whether the JAR file is on a network share.
The first part you need to do is to obtain the absolute path for the JAR file:
Class mainClass = MyMainClass.class;
File jarFile = new File(mainClass.getProtectionDomain()
.getCodeSource()
.getLocation()
.toURI());
I found a "gist" on github written by Aaron Digulla that does the second rest of the task:
https://gist.github.com/digulla/31eed31c7ead29ffc7a30aaf87131def
Aaron's code takes a Windows absolute path, extracts the drive letter and then runs the Windows net use <drive-letter>: command to test whether the drive is a share drive.
An alternative would be to implement the logic a batch file does the following:
Extract the drive name for the JAR file
Use net use ... to test for a share drive
Use the same technique to check that the Java installation is not on a share drive either1.
Use the java command to start the application
Finally, is probably a bad idea to refuse to run on a share drive. The user may have reasons to do this that you are not aware of. I would suggest prompting the user and giving the user the option of continuing anyway. Or something like that.
Alternatively, document in the application's installation instructions that it is inadvisable to install the JRE / JDK and the application on a share drive (or equivalent).
1 - A Java install on a share drive will give as bad if not worse performance than an application JAR on a share drive.
I've used Commons IO to write a program that copy files and other things. But I want to copy a file to a local ip address \\10.x.x.x, but the user doesn't have rights to do the copy, so I need to put an ID and password to access it. However I cannot find a way I can do that.
To move file I use :
FileUtils.moveFileToDirectory(fichier, destDir,true);
But my directory is something like \\10.x.x.x\files and only a few users can write in that directory so I have an ID & password that let you move files there. I want that even if the users don't have rights to move files to that directory my program can do it.
It is not really the way Windows security works. If you really want to do it that way, you will have to use Java Native Interface or Java Native Access, and manage to call the WNetAddConnection function from Mpr.dll (and do not forget to call WNetCancelConnection when done).
But you would have to store a password in your program, which is poor security practice.
The standard way to do that would be to start a service that would run under a user that has access to the desired directory, and have your program to communicate with it using whatever you want, the simplest way being probably TCP/IP. But unless you have special requirement for that I would not recommend to use Jave for those kinds of program.
A more Java alternative would be to start a Tomcat service on server machine running under a user having access to the directory. That way you just have to develop a standard Java Web Application able to upload files that would save the files to the proper directory. But it would be a traditionnal and portable Java application with no need for JNI nor JNA.
If cannot use a Tomcat and do not want to invest to much on it, you could split the program in pieces :
one client program that copies files on a directory (on server machine) with File creation rights for everybody - can decays to the copy utility if nothing more has to be done or can easily written in Java
one server program that will run on server machine under a user that has full write permissions on target directory. This one can also be easily written in Java
you can easily install the server program as a service on the server machine with sc and srvany according to this answer on ServerFault
If you use a client program, you could easily add a digital signature file with each copied file, but as I said above, it is poor security practice and add little if any security. At least the program should be executable and not readable, and the sources should be kept hidden. It is better to log the users that copied the file and ask them what happened is you find a problem.
I have created a group of some users. Now I don't want these users to access the c:/ drive, so I need to hide the c:/ drive and unhide it when not required. I also want to redirect the entire d:/ drive to the network drive, so, how can both these things i.e. hiding/unhiding the local directory and re-direct drive on to a network drive be done using java?
thanku :)
You can't really do that...
BUT...
If this is in the context of an application alone, and you can use Java 7 or more, you do have the option of providing your own default FileSystemProvider.
This can be quite some work, however...