Call native methods in a DLL from Java without JNI
Posted 2007-05-27 in Java by Johann.
In this example, we will monitor a directory without continously polling it’s contents. Instead, we’ll rely on the Windows API that we access through NativeCall – that is, without JNI.
The functions
To monitor the directory, we need the following functions:
CreateFileA
to create a handle to the directory.CloseHandle
to close the handle.ReadDirectoryChangesW
to monitor it for changes.
These functions are all implemented in kernel32.dll
. Fortunately, this is the default DLL in NativeCall so we don’t need to specify it.
Getting started
After unpacking the NativeCall distribution, we add the JAR to the CLASSPATH
and set up java.library.path
to point to the directory with the NativeCall native library in it. We then initialize NativeCall by calling NativeCall.init()
.
Functions
We obtain references to the functions with the following code:
IntCall createFile = null; IntCall closeHandle = null; IntCall readDirectoryChanges = null; int dirHandle = 0; try { createFile = new IntCall("CreateFileA"); closeHandle = new IntCall("CloseHandle"); readDirectoryChanges = new IntCall("ReadDirectoryChangesW"); … } finally { if (closeHandle != null) { if (dirHandle != 0) { closeHandle.executeBooleanCall( new Integer(dirHandle)); } closeHandle.destroy(); } if (readDirectoryChanges != null) { readDirectoryChanges.destroy(); } if (createFile != null) { createFile.destroy(); } }
Calling destroy
in a finally
block is important to ensure that all resources are freed. If you forget this, you will leak memory.
Directory handle
The directory handle is acquired with the following code:
dirHandle = createFile.executeCall(new Object[] { new Integer(dirHandle), DESIRED_ACCESS, SHARE_MODE, null, CREATION_DISPOSITION, FLAGS_AND_ATTRIBUTES, null });
The constants you see are simple Integer
s.
Monitoring the directory
All that’s left to do now is to call the ReadDirectoryChangesW
method. In this example, this is a synchronous call which will block until the directory is changed.
Holder returnedBufferLength = new Holder(0); byte[] buffer = new byte[1024]; Arrays.fill(buffer, (byte) 0xff); Holder fileNotifyInformation = new Holder(buffer); readDirectoryChanges.executeBooleanCall(new Object[] { directory.getCanonicalPath(), fileNotifyInformation, new Integer(buffer.length), false, NOTIFY_FILTER, returnedBufferLength, null, null });
Get the code
Download DirectoryMonitor.java
and DirectoryMonitorTest.java
, the test case and start hacking.
15 comments
panscient.com = bad bot
Posted 2007-05-23 in Spam by Johann.
Another one for the garbage can. It creates bad requests and doesn’t respect robots.txt
although they claim to do so.
38.99.203.110 … "GET / HTTP/1.1" … "panscient.com" (robots.txt not asked for) 38.99.203.110 … "GET /;5B=/ HTTP/1.1" … "panscient.com" (WTF?) 38.99.203.110 … "GET /<prohibited directory> HTTP/1.1" … "panscient.com"
7 comments
Mozilla/4.0 (compatible;)
Posted 2007-05-09 in Spam by Johann.
When I first published this entry in May 2007, I thought this was just another web scraper.
… "GET / HTTP/1.1" 200 7518 "-" "Mozilla/4.0 (compatible;)" "-" … "GET /help/copyright.html HTTP/1.1" 200 4127 "-" "Mozilla/4.0 (compatible;)" "-" … "GET /help/sitemap.html HTTP/1.1" 200 4902 "-" "Mozilla/4.0 (compatible;)" "-" … "GET /favicon.ico HTTP/1.1" 200 11502 "-" "Mozilla/4.0 (compatible;)" "-" … "GET /misc/common.css HTTP/1.1" 200 894 "-" "Mozilla/4.0 (compatible;)" "-"
Blue Coat proxies
With a little header analysis, I now know that these requests are caused by Blue Coat’s proxy products. These proxies seem to employ a pre-fetching strategy, meaning they analyze pages as they download them and follow links so that future requests can be served from the proxy cache.
Who uses their proxies? I think Hewlett-Packard do, I know Citigroup and Nokia do. In fact I think a lot of companies have their proxies installed judging from the entries in my header log file.
Blue Coat’s stealth crawling
I could live with the fact that their software makes a ton of highly speculative requests but Blue Coat also have been stealth scanning my web site (most likely for malware) – just like Symantec.
Java UUID generators compared
Posted 2007-04-25 in Java by Johann.
UUIDs (or GUIDs) are unique identifiers that are frequently used in programming. In this entry, I will compare three generators of UUIDs written in the Java programming language.
Possible uses for UUIDs
UUIDs have a variety of uses, including
- Temporary file names.
- Unique identifiers for website visitors.
- Transaction IDs.
- Primary keys, replacing database sequences.
Generally, whenever unique values across different machines are needed, UUIDs are a good choice.
The contestants
The following packages were compared:
- UUID – my own implementation.
- Java UUID Generator.
java.util.UUID
, available since JDK 5.
I did not compare the following packages:
- The implementation found in Jini.
- Commons Id – there is no release as of now.
The features
I compared the following features:
- Ease of use: How many lines of code does it take to get a UUID?
- Versions: The UUID versions supported (1–5).
- Speed: The performance of generating UUIDs.
- EJB: Whether the generated UUIDs can be used as primary keys in enterprise java beans.
- CORBA: Whether the generated UUIDs can be used in CORBA.
- Parse: Whether parsing UUIDs is supported. Usually, this is done from
java.lang.String
s, although JUG also supports parsing frombyte
arrays.
The results
Name |
Ease of use |
Versions |
Speed |
EJB |
CORBA |
Parse |
---|---|---|---|---|---|---|
++: very good, +: good, o: acceptable, -: bad, --: very bad |
||||||
UUID |
++ |
1 |
++ |
Yes |
Yes |
|
JUG |
o |
1, 3–5 |
+/-/-- |
No |
No |
|
JDK 5 |
++ |
3, 4 |
-/-- |
No |
No |
|
The benchmark
The performance of all generators was compared. The test computer was an Intel Pentium M 1.73 GHz computer with 1.5 GB of RAM. Load on the computer was low during the tests.
The following Java Virtual Machines were used:
- Sun JDK 1.5.0_05
- IBM 1.3.1
- Sun 1.4.2_09
- BEA JRockit 1.4.2_08
- BEA JRockit 1.5.0_08
- Sun JDK 6
All Java Virtual Machines were started with -Xms256M -Xmx256M
to force a fixed VM size.
The data
The following table contains the timings in milliseconds for the creation of one million UUIDs with the various implementations.
VM |
UUID |
JUG, time |
JUG, name |
JUG, random |
JDK, random |
JDK, name |
---|---|---|---|---|---|---|
Sun 1.5.0_05 |
1315 |
3424 |
25518 |
25946 |
28565 |
35253 |
IBM 1.3.1 |
2359 |
6796 |
81134 |
46584 |
||
Sun 1.4.2_09 |
2800 |
7053 |
91569 |
64956 |
||
JRockit 1.4.2_08 |
2556 |
5859 |
63890 |
47500 |
||
JRockit 1.5.0_08 |
1431 |
3756 |
25653 |
35093 |
35797 |
32253 |
Sun JDK 6 |
2303 |
5703 |
35968 |
41100 |
41553 |
48859 |
My own implementation is the fastest by a factor of at least two. With a modern computer, it is possible to generate more than 500.000 UUIDs per second.
The good
All of the implementations I tested generated unique UUIDs, even when used multi-threaded.
The bad
Some of the implementations are slower than others. It might not be possible to use some implementations in environments like EJB containers.
The MAC address issue
The computer’s MAC address must be encoded into a version 1 UUID. Because there is no official way in Java to do this, JUG comes with a native library (compiled for Windows x86, FreeBSD, Linux x86, MacOSX PPC, SPARC). My own version does this without native code (tested on Windows, Linux, MacOSX, BSDs, Solaris, HP-UX) and falls back to random data if the MAC address cannot be read.
Security aspects must be considered when version 1 UUIDs that contain the MAC address are made public.
The summary
If you need speed and/or support for EJBs or CORBA, UUID is the best way. If security is of ultimate importance to you, it cannot be used. In that case, JUG in the time-based mode is a good choice.
2 comments
Pages
Page 18 · Page 19 · Page 20 · Page 21 · Page 22 · Page 23 · Page 24 · Next Page »
Subscribe
RSS 2.0, Atom or subscribe by Email.
Top Posts
- DynaCloud - a dynamic JavaScript tag/keyword cloud with jQuery
- 6 fast jQuery Tips: More basic Snippets
- xslt.js version 3.2 released
- xslt.js version 3.0 released XML XSLT now with jQuery plugin
- Forum Scanners - prevent forum abuse
- Automate JavaScript compression with YUI Compressor and /packer/