Java Changing Linux File Permission Sometimes Does not Work - java

I am working on a task, which is changing the file's permission to 640 after our code exports the file to our Linux server. The same code works in our Dev server, but in our Uat server, sometimes the permission is changed to 640 successfully, sometimes the permission can not be changed, is still the default 600.
I checked the SystemOut.log, no any error for this.
My related Java code is like below:
private void exportXXXFiles() {
......
//Settings for the access permissions of the exported files
Set<PosixFilePermission> filePerms = new HashSet<PosixFilePermission>();
filePerms.add(PosixFilePermission.OWNER_READ);
filePerms.add(PosixFilePermission.OWNER_WRITE);
filePerms.add(PosixFilePermission.GROUP_READ);
try {
Path localFilePath = ......;
Files.setPosixFilePermissions(localFilePath, filePerms);
......
} catch (IOException e) {
e.printStackTrace();
}
}
I am confused why the same code works in our Dev server but not stable in our Uat server, where sometimes it works sometimes it does not work. I assume that is the environment issue, but I have no idea what the exact issue is. Who can give me some suggestions?
Thanks!

There are a few reason why changing permissions might not work. These include:
The application doesn't have permission to change permissions. With classic UNIX / Linux, you need to be the file owner or root to change an file's permissions. Then there are ACLs.
The file system might be read-only, or mounted read only.
The file system type might not support the combination of permissions you are trying to use. For example, FAT did not support execute permissions, and NTFS permissions work a bit differently. Unfortunately, when you mount a "foreign" file system type on Linux, the OS doesn't provide a way to direcrly manipulate the file system's native permissions.
It is possible that what you are trying to do is blocked by SE Linux or AppArmor or similar.
Now, some of these may result in a Java exception when you attempt to change the permission. But that is up to the OS and the file system drivers. Java can only throw an exception if the OS tells Java that the permission change attempt failed, and it can only report / interpret the reason (the errno) returned by the chmod syscall.

Related

How to open TestComplete from java code

I would like to open TestComplete from java, but I can't do that, because lack of privilege. When I run my code
public static void StartTC() {
try{
Process p = Runtime.getRuntime().exec(new String[] {"C:\\Program Files (x86)\\SmartBear\\TestComplete 11\\Bin\\TestComplete.exe"});
}
catch (IOException e) {
e.printStackTrace();
}
}
the program exits with CreateProcess error=740, and tells me that I need higher privilege for this action.
I know that I could make a .lnk with admin priv. at open properties of the exe, but there could be a right way to do this.
I think you can use File class for setting permissions.
File file = new File("File.c");
//but file permission are OS specific.
file.setExecutable(true);
In linux it will work.
If you are using windows then you can run "icacls" command to give permission to the file.
C:\>icacls "D:\test" /grant John:(OI)(CI)F /T
This command can be used to to give permission in windows.
According do MS documentation:
F = Full Control
CI = Container Inherit - This flag indicates that subordinate containers will inherit this ACE.
OI = Object Inherit - This flag indicates that subordinate files will inherit the ACE.
/T = Apply recursively to existing files and sub-folders. (OI and CI only apply to new files and sub-folders). Credit: comment by #AlexSpence.
You can run above command using Runtime.getRuntime().exec("icacls something here");
I hope I helped you.
You need to disable the Tools | Options... | Engines | General | Enable support for testing Windows Store applications option in TestComplete.
Information on how this can affect working with TestComplete from an external application like in your case can be found in the Requirements for Testing Windows Store Applications help topic.

java.io.IOException: The system cannot find the path specified

On a particular server (Windows 2012 server R2) I am having trouble creating a temp file. I get the following error everytime I try.
java.io.IOException: The system cannot find the path specified
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createTempFile(Unknown Source)
etc..
The error happens everytime the following code is ran:
InputStream inputStream = portalBean.createPDF( sessionID, foCode );
Things I have tried
Changed the java.io.tmpdir variable on the fly. System.setProperty("java.io.tmpdir", "C:\\");
Added -Djava.io.tmpdir=c:\\temp to the webnetwork lax file to an unrestricted location.
I tried setting the webNetwork service to run as a specified user with rights to temp files e.g. the Administrator.
Made sure I have free disk space and I cleaned out the c:\windows\temp folder.
Made sure the tmp environment variables were set to their default values.
I also tried running the service from a command prompt which was opened with the Run As Administrator option.
And the IOException lingers still. I have another server running the same code without issue (Windows Server 2012).
Does anyone else have any Ideas of what else I can try to resolve this issue? And or any tips on how I can debug the issue more thoroughly to get a grasp of what is going on?
One tool you can use to debug this is process monitor from system internal tool kit. The step is: add a filter to only monitor your process (I think it is javaw.exe in your case), after the error happens, go through the file activities in the process monitor log, you can find how the process is finding files and which directories the process searched. If the process is searching in the wrong directory, you can find it from the log.
I just used this tool to figure out a JVM crash problem today.
Based on the description of your problem, I guess the path variable of the process is changed in the middle of your code, with another tool process explore you can view the path variable of the process, it might help.
Try and create instead a directory somewhere under your home directory:
final Path tmpdir = Paths.get(System.getProperty("user.home"), "tmp");
Files.createDirectories(tmpdir);
System.setProperty("java.io.tmpdir", tmpdir.toAbsolutePath().toString());
Then try and Files.createTempFile() in there.
Note that if Files.createDirectories() refers to an existing file which is not a directory, you'll get a FileAlreadyExistsException.

java.lang.RuntimePermission when running a applet from the web application

I'm trying to read a envrionment varaible from a applet, here is my code
String env = System.getenv("TWS");
System.out.println(env);
Runtime rt = Runtime.getRuntime();
String s = env + "\\WebStart.bat " ;
System.out.println(s);
try {
Process p = rt.exec(s);
} catch (Exception e) {
}
when i run the code from netbeans by right click and run, it is running without a problem.
but when i put it to a jar file, add it to my web application and try to run it from a html page using the following code
<applet code="draw.class" archive='AppletTest.jar'>
<param name="shape" value="triangle"/>
</applet>
i'm getting a error saying access denied , java.lang.RuntimePermission
i am running this web application using tomcat 6.
i have read some guides and added the following entry to catalina.policy file in tomcat 6 and restarted tomcat
permission java.lang.RuntimePermission "accessDeclaredMembers";
but still the same warning. can some one please suggest a solution for this problem?
--rangana
When you run your applet from netbeans, Java virtual machines runs it under a different security regime than when you run it through browser.
Applets, downloaded through browsers, that are not signed using a security certificate, are considered to be untrusted and referred to as unsigned applets. When running on a client, unsigned applets operate within a security sandbox that allows only a set of safe operations. You can check if a perticular permission is granted to you applet or not by using SecurityManager. For example in your case :
System.getSecurityManager().checkPermission(new RuntimePermission("accessDeclaredMembers"));
You can know more about applet security here and here. A very nice tutorial on making signed applets can be found here.

java.io.IOException: Permission denied on network folder

i'm having the the post's title error when trying to write a file on a window folder , mounted on unix system. I've developed a web service which runs inside a Tomcat 6 on a linux os and need to write on a windows network folder. System administrators have mounted it on the Linux sever and have no problem to create and modify a file on it.
When i try to execute the posted code i get the following exception :
Permission denied
java.io.IOException: Permission denied
at java.io.UnixFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:850)
The weird thing is that it seems to be related to the File.createNewFile method on a network folder , in fact the service can write on local file system without problems, both on debug (the pc i use to develop the service) and a tomcat folder system administrators have provided me on the linux server. The file gets created but is empty and the log entry following the create method doesn't get printed. Moreover if i use a plain outputstream to create and write the file i've no problems.
I cannot find any explanation about the exception on the web. Since i'm not very experienced with java , i'd like to understand why i'm getting this error. Am i using it in the wrong way ? Is it a bug of the library ? Do i miss to pass some parameter ?
As stated , i've solved the problem using a plain outputstream, this is a question to improve my understanding of java.
FileOutputStream fos = null;
try{
log.info(String.format("file length: %s",streamAttach.length));
log.info(String.format("check File : %s",filename));
File f = new File(filename);
if(f.exists())
...
boolean done= f.createNewFile();//here comes the exception
//nothing of the following happens
if(!done)
throw new NWSException("error creating file");
log.info(String.format("file %s creato", nomeFile));
thank you in advance for any answer
I ran into this problem recently and found that java.io.File.createNewFile() actually requires the "Change Permissions" permission (you can find this entry under Security->Advanced when checking folder permissions). Without this it will create the file and then subsequently throw an IOException.
It's deceptive because you will still be able to create files on the folder when manually testing, however createNewFile() will still fail if it doesn't have this particular permission (presumably such that it can change the permissions on the file its creating).
If you are using Netapp that shares an NTFS (CIFS) style filesystem to Unix you could be experience "NFS is not allowed to change permissions on a file in an NTFS-style security volume." (TR-3490 page 16)
Options here are to change to a unix filesystem or set the cifs.ntfs_ignore_unix_security_ops flag to on for the file system which quiches the NFS permission error.
java.io.UnixFileSystem.createFileExclusively(Native Method) opens the file with the O_EXCL and 0666 umask so I would get a EACCES, which really was a NFS3RR_ACCES
open("/net/storage01-a/filer/myfile", O_RDWR|O_CREAT|O_EXCL, 0666) Err#13 EACCES
Also you can use OutputStream to create the file, that does not use O_EXCL it seemes
It definitely not Java specific problem. If this Unix folder is mapped to your windows try to open file explorer and create file in this directory. I believe that you will get permission denied too. In this case fix this problem or ask your system administrator to help you.
Good luck!

How to copy a file from Linux System to Windows system using Java program?

How to copy a file from Linux System to Windows system using Java program?
Thanks for your help.
I want to copy file from linux : /inet/apps/test.java to windows System1: C:\apps\test
We can use following program to copy
public static void copyFiles(String fromFile, String toFile ){
FileInputStream from = null;
FileOutputStream to = null;
try {
from = new FileInputStream(fromFile);
to = new FileOutputStream(toFile);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = from.read(buffer)) != -1)
to.write(buffer, 0, bytesRead); // write
}catch(Exception e){e.printStackTrace();}
finally {
if (from != null)
try { from.close();} catch (IOException e) {}
if (to != null)try {to.close();} catch (IOException e) {}
}
}
This program is running on linux.
so fromFile = /inet/apps/test. What will be the toFile path. If i use simply C:\apps\test then how applicaiton recognise the target as System1.
Java makes no diffeence between Windows and Linux files. So, as long as you have access to both filesystem in the computer your java program is running, you can just copy them.
I think you are asking about some
properties for the program.
In that case the properties, should
be configurable. You can keep the
properties file in the same
directory as your Java program or in
the class path.
The property file might look like :
windows.filepath = C:\user\somefile.txt
unix.filepath = /inet/apps/test.txt
So when you port environments. You
don't need to change the properties.
If you are asking about how to port
test.java to windows, then just copy
the file to JAVA_HOME directory on
windows and then you are good to go.
Or If you have a Dual boot system.
You can access your linux drive
from windows, but not the other
way around.
If the Unix system has the Window file system cross-mounted (e.g. via an SMB share), you should be able to find the Unix pathname that corresponds to the Windows destination and copy as you are currently doing.
Otherwise, you will need to use a file transfer protocol of some kind to copy the file.
There's no Java magic that allows you to magically write files to a different computer. The operating system has to be set up to allow this to happen.
FOLLOW UP - you asked:
I have no thought about the magic. So my question was how to copy a file from Windows to Linux. Normally we do FTP on unix Without mounting or we use FileZilla tool to transfer happens. Here if we want to do same thing though java then how to do that?
I don't know how I can say this differently to make you understand, but here goes:
Your choices in Java are basically the same:
You can use FTP. For example on the destination machine, turn pathname of the source file into a "ftp://..." URL, and use java.net.URL.connect() to pull it. There are probably 3rd-party Java libraries that you can use to "push" the file to a FTP server.
If your OS is setup with the file systems cross-mount, you can do a regular file copy, much as your code does.
You can use java.lang.System.exec(...) to run some Windows specific command line utility to do the copying.
In all cases, you will need to figure out how to map pathnames between the Windows and Linux worlds.
You can try the copy() method of the java.nio.file.Files class, of course we assume that your application can access both the path on Linux and Windows either by mapping the folders or something similar. For example
Files.copy(Paths.get(source), Paths.get(destination), StandardCopyOption.REPLACE_EXISTING, COPY_ATTRIBUTES);

Categories

Resources