How can I check if my application can create a symbolic link? - java

From my Java application I want to create a symbolic link. However my application can run in different circumstances, not all of those permit the creation of symbolic links. I have the following situations:
Linux - can always make a symlink
Windows - can make a symlink if you are running the application as an administrator.
To create the symlink I use Files.createSymbolicLink(). This throws an IOException under Windows when it doesn't have permission. To be precise the exception is:
java.nio.file.FileSystemException: test\link: A required privilege is not held by the client.
I want to be able to tell if I have this permission from the application (Java 7 or newer) before trying to make the symlink. How can I do this?

This code bellow will work only for Windows and comes with Java.
public static boolean AdminAuth() {
String groups[] = (new com.sun.security.auth.module.NTSystem()).getGroupIDs();
for (String group : groups) {
if (group.equals("S-1-5-32-544"))
return true;
}
return false;
}
The SID S-1-5-32-544 is the id of the Administrator group in the Windows operating system.
You can also take a look at this documentation regarding Application Manifest for Windows.

Related

Java Changing Linux File Permission Sometimes Does not Work

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.

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.

How to enumerate connected USB storage devices Ubuntu Java

I have an application, mostly in Java' that controls an airborne infrared camera via a webpage GUI (served by the Ubuntu machine) which starts running automatically when the computer is powered up and towards the end of the boot. The application runs as a user, not root, even though the user is not logged in.
After a great many images are collected the data need to be archived by using rsync to a folder on the operator's USB drive. I need to have the USB drive mounted and know its name tag. The computer is headless and the operator, who is on the aircraft, cannot be expected to know Linux in any case.
On an Ubuntu I see that logged in and running the xfce4 GUI, and only then, the drives are listed in /media/user-name/drive-tag (I note that /media/username is owned by root but the folder named for the drive is owned by the user.) and are shown in /etc/mtab :
/dev/sdd1 /media/programmer/DATA-02-2TB vfat rw,nosuid,nodev,uid=1001,gid=1001,shortname=mixed,dmask=0077,utf8=1,showexec,flush,uhelper=udisks2 0 0
How can I, through Java or through a combination of Java and bash, detect and mount a USB storage device?
If that's not possible do I need to ask the user, through the GUI, to enter the device tag or name, e.g., 'DATA-02-2TB' and then create the mount point and mount the USB drive via a script using the information above?
First install usbmount, a Ubuntu tool.
sudo apt-get update
sudo apt-get install usbmount
Then edit the /etc/usbmount/usbmount.conf file:
sudo sed -i 's/MOUNTOPTIONS="/MOUNTOPTIONS="user,umask=000,/' /etc/usbmount/usbmount.conf
These steps are described at Serverfault. Note that only a subset of drive formats is supported including the ubiquitous VFAT.
With this in place USB external drives and thumb drives will mount in /media as /media/usb0 through /media/usb7 and will be listed in /etc/mtab.
/dev/sdc1 /media/usb0 vfat rw,noexec,nosuid,nodev,sync,noatime,nodiratime,umask=000 0 0
I've tested this on my 14.04 machine. Now if I could only get the drive label.
Edit: The sync option does not work well with flash drives. Read the /etc/usbmount/usbmount.conf file for details and remove "sync" from the appropriate line in that file. A full backup made with sync option ran for over an hour before I cancelled it but took only about 5 minutes with sync removed. Note the comment about using pumount to unmount the non-synched drive.
public static ArrayList<String> usbDriveList() throws FileNotFoundException {
final String MTB_ADDRESS = "/etc/mtab";
final String TARGET = "^/media/usb[0-7]$"; // REGEX
final File file = new File(MTB_ADDRESS);
final ArrayList<String> driveList = new ArrayList<String>();
try (Scanner in = new Scanner(file)) {
while (in.hasNext()) {
final String[] splitLine = in.nextLine().split(" ");
if (splitLine[1].matches(TARGET)) {
driveList.add(splitLine[1]); // got it!
}
}
} catch (final FileNotFoundException e) {
throw new FileNotFoundException();
}
return driveList;
}

Where does Grails 2.1.0 / Java 7 get the current user name from on Windows 8.1?

I need to use Grails 2.1.0 (specifically that version) and have installed this on Java 7 (ditto specific version) by extracting it to "C:\Users\new.username\grails\grails-2.1.0\grails-2.1.0" Unfortunately when I run grails I get an error as follows:
C:\>grails
Caching deactivated: failed to create cache directory: C:\Users\old.username\.grails
Exception: java.lang.RuntimeException thrown from the UncaughtExceptionHandler in thread "main"
This seems to show that either Grails or Java is picking up an old user name that Windows was created with and I need to know where this is being gotten from and how to change it to my current user "new.username" ?
I have looked through the registry and removed everything I dare that had old.username in it but am too scared to remove everything...
Any ideas ?
It's available in the environment, and you can access the values via System.getenv(). Both HOMEPATH and USERPROFILE point to my home directory when I tried this just now on a Windows machine, and my username showed up in USERPROFILE, LOCALAPPDATA, USERNAME, and APPDATA.
I recommend a ceremonial destruction by fire and the purchase of a Linux-based laptop, but not in that order.

Starting a Java application at startup

I have a Java application.
The application has a setting that decides whether or not the application starts at startup.
Currently, I have it this by placing/removing a shortcut in the StartUp items folder.
However, I am wondering if there is a better way to handle this behaviour.
EDIT
Yes, it's Windows. Sorry for not clearing that before.
The application has an UI where the user may trigger actions, also the application runs a few tasks in the background periodically while running.
#Peter, how could I change the registry with code from within the application? Is that approach compatible with all versions of Windows?
Below is a small example snippet of how it can be done from inside your application
static final String REG_ADD_CMD = "cmd /c reg add \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" /v \"{0}\" /d \"{1}\" /t REG_EXPAND_SZ";
private void exec(String[] args) throws Exception
{
if (args.length != 2)
throw new IllegalArgumentException("\n\nUsage: java SetEnv {key} {value}\n\n");
String key = args[0];
String value = args[1];
String cmdLine = MessageFormat.format(REG_ADD_CMD, new Object[] { key, value });
Runtime.getRuntime().exec(cmdLine);
}
I'm pretty sure this will work with all versions of Windows since they all use the same Startup\Run registry entry.
Hope that helps! :)
Credit
On Windows I have used open source Java Service Wrapper to make our application as window service which you can setup automatic at startup.
What you need to do is to download latest wrapper.exe and create wrapper.config file put all the configuration like Main class any VM arument other parameters in defined standards and create a window service by this exe
Use the Registry to start your program at the startup and then it will be shown in the list provided by msconfig commnd through Run.
Use this registry path
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

Categories

Resources