Getting the file owner in Java using JNI

Since i needed this for a project, I thought it was worth a post.

Basically I needed to watch a directory for incoming files and perform a given action based on the owner of the file, in Java.

For the polling part, no problem, but how can I get the owner of a file in Java ? Well after 1 hour searching the internet and concluding that :

  • It is not possible in pure Java at least up to 1.5
  • It should be done using native code through JNI

I decided to give it a shot since I had another hour in front of me. Here a the steps I followed :

1. Try to find some code that does this in C++ : http://msdn2.microsoft.com/en-us/library/aa446629.aspx

2. Try to compile this code :-) Since I have no Visual Studio or other C++ IDE, let’s go find one .. :

http://www.bloodshed.net/devcpp.html

3. Install Dev++ and compile the code .. and to my great surprise, it works (I must say I have bad college memories about C++, compilers, make files, compiler directives, etc…)

4. Now let’s tackle the JNI part .. since I never used JNI before (but know what it’s about), I type ‘jni tutorial’ in google .. and find :

http://www.codetoad.com/java_simpleJNI.asp

I chose this page because it seemed to have an example of passing a String parameter and getting back a String result – which is exactly what I need since I will pass a file path and get back the file owner.

5. Create a java class

import java.io.*;
public class getowner
{
	private static native String getowner(String arg);
        public static void main(String[] args)
	{
	 	System.load("c:/temp/java/getowner.dll");
		File f = new File(args[0]);
		File[] children = f.listFiles();
		for (int i=0; i < children.length;i++)
		{
			if (children[i].isFile())
				System.out.println(getowner(children[i].getPath()));
	 	}
	}
}

6. Compile the class and generate the header file using javah

javac getowner.java
javah getowner

Which generates the following header file :

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class getowner */

#ifndef _Included_getowner
#define _Included_getowner
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     getowner
 * Method:    getowner
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_getowner_getowner
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

7. Write the implementation by modifying the code used in step 2

(see attachment for the complete source code)

8. Compile the whole thing, don’t forget in the project settings to add 2 include directories pointing to the JDK include and include/win32 folder

If you’re lucky you should get a nice getowner.dll file

9. You can now run the java program :

java getowner c:windows

which will output the owner of all the file in you windows directory.

You can download the source code zip getowner.zip that contains :

  • the project file
  • the cpp source file
  • the generated header file
  • the java class

Have fun !

P.

4 Responses - Leave yours here.

  • Yes, not that complicated in the end. My first cup of JNI also tasted surprisingly good.
    If you ever need to pass Windows Messages to applications from Java, check out the Java Desktop Integration Components, and in particular the Media Control API, at
    https://jdic.dev.java.net/incubator/mpcontrol/index.html
    (see org.jdesktop.jdic.mpcontrol.winamp package)

  • Hi,

    I needed the same C++ code for a program I am writing. Note that the MS sample code will leak memory and file handles if you don’t make some changes:
    The HANDLE returned by the CreateFile call needs to be closed (CloseHandle) before the function returns. Also, all memory allocated by GlobalAlloc needs to be freed with GlobalFree.

    Gert

  • Hi Gert,

    I did not post an update but I quickly noticed the file close issue so this has already been added.

    But thanks for the GlobalFree hint, I will add it right away :-)

    I’ll try to post an update of the code when it is ready

    P.

  • Guillermo Delgado

    August 31st, 2007 at 11:44 am

    Hi to everyone,

    First of all I want to say thanks to Pierre-Alexandre for the help. It was very useful for me.

    My problem is that I need the getowner.dll to be inside the MyProyect.jar file. This means that I can´t use the absolute route you are using in getowner.java.

    does anyone have any idea??

    thanks in advance

Leave a comment

Your email will not be published. Required fields are marked *.