root / trunk / build / distribution / IzPack / src / lib / com / izforge / izpack / util / Librarian.java @ 21757
History | View | Annotate | Download (24.7 KB)
1 |
/*
|
---|---|
2 |
* $Id: Librarian.java 5819 2006-06-14 07:29:09Z cesar $
|
3 |
* IzPack
|
4 |
* Copyright (C) 2002 by Elmar Grom
|
5 |
*
|
6 |
* File : Librarian.java
|
7 |
* Description : Supports the loading of native libraries
|
8 |
* Author's email : elmar@grom.net
|
9 |
* Website : http://www.izforge.com
|
10 |
*
|
11 |
* This program is free software; you can redistribute it and/or
|
12 |
* modify it under the terms of the GNU General Public License
|
13 |
* as published by the Free Software Foundation; either version 2
|
14 |
* of the License, or any later version.
|
15 |
*
|
16 |
* This program is distributed in the hope that it will be useful,
|
17 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19 |
* GNU General Public License for more details.
|
20 |
*
|
21 |
* You should have received a copy of the GNU General Public License
|
22 |
* along with this program; if not, write to the Free Software
|
23 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
24 |
*/
|
25 |
|
26 |
package com.izforge.izpack.util; |
27 |
|
28 |
import java.io.File; |
29 |
import java.io.FileNotFoundException; |
30 |
import java.io.FileOutputStream; |
31 |
import java.io.InputStream; |
32 |
import java.io.OutputStream; |
33 |
import java.net.URL; |
34 |
import java.security.CodeSource; |
35 |
import java.security.ProtectionDomain; |
36 |
import java.text.CharacterIterator; |
37 |
import java.text.StringCharacterIterator; |
38 |
import java.util.Vector; |
39 |
|
40 |
/*---------------------------------------------------------------------------*/
|
41 |
/**
|
42 |
* This class handles loading of native libraries. There must only be one
|
43 |
* instance of <code>Librarian</code> per Java runtime, therefore this class is
|
44 |
* implemented as a 'Singleton'.
|
45 |
* <br><br>
|
46 |
* <code>Librarian</code> is capable of loading native libraries from a
|
47 |
* variety of different source locations. However, you should place your
|
48 |
* library files in the 'native' directory. The primary reason for supporting
|
49 |
* different source locations is to facilitate testing in a development
|
50 |
* environment, without the need to actually packing the application into
|
51 |
* a *.jar file.
|
52 |
*
|
53 |
* @version 1.0 / 1/30/02
|
54 |
* @author Elmar Grom
|
55 |
*/
|
56 |
/*---------------------------------------------------------------------------*/
|
57 |
public class Librarian implements CleanupClient |
58 |
{ |
59 |
// ------------------------------------------------------------------------
|
60 |
// Constant Definitions
|
61 |
// ------------------------------------------------------------------------
|
62 |
|
63 |
/** Used to identify jar URL protocols */
|
64 |
private static final String JAR_PROTOCOL = "jar"; |
65 |
/** Used to identify file URL protocols */
|
66 |
private static final String FILE_PROTOCOL = "file"; |
67 |
/** The key used to retrieve the location of temporary files form the
|
68 |
system properties. */
|
69 |
private static final String TEMP_LOCATION_KEY = "java.io.tmpdir"; |
70 |
/** The extension appended to the client name when searching for it as a
|
71 |
resource. Since the client is an object, the extension should always
|
72 |
be '.class' */
|
73 |
private static final String CLIENT_EXTENSION = ".class"; |
74 |
/** The default directory for native library files. */
|
75 |
private static final String NATIVE = "native"; |
76 |
/** The block size used for reading and writing data, 4k. */
|
77 |
private static final int BLOCK_SIZE = 4096; |
78 |
|
79 |
// ------------------------------------------------------------------------
|
80 |
// Variable Declarations
|
81 |
// ------------------------------------------------------------------------
|
82 |
|
83 |
/** The reference to the single instance of <code>Librarian</code>. Used
|
84 |
in static methods in place of <code>this</code>. */
|
85 |
private static Librarian me = null; |
86 |
/** A list that is used to track all libraries that have been loaded.
|
87 |
This list is used to ensure that each library is loaded only once. */
|
88 |
private Vector trackList = new Vector (); |
89 |
/** A list of references to clients that use libraries that were
|
90 |
extracted from a *.jar file. This is needed because the clients
|
91 |
need to be called for freeing their libraries. */
|
92 |
private Vector clients = new Vector (); |
93 |
/** A list of library names as they appear in the temporary directory.
|
94 |
This is needed to free each library through the client. The index
|
95 |
of each name corresponds to the index of the respective client in
|
96 |
the <code>clients</code> list. */
|
97 |
private Vector libraryNames = new Vector (); |
98 |
/** A list of fully qualified library names. This is needed to delete
|
99 |
the temporary library files after use. The index of each name
|
100 |
corresponds to the index of the respective client in the
|
101 |
<code>clients</code> list. */
|
102 |
private Vector temporaryFileNames = new Vector (); |
103 |
/** The extension to use for native libraries. */
|
104 |
private String extension = ""; |
105 |
/** The directory that is used to hold all native libraries. */
|
106 |
private String nativeDirectory = NATIVE; |
107 |
|
108 |
/*--------------------------------------------------------------------------*/
|
109 |
/**
|
110 |
* This class is implemented as a 'Singleton'. Therefore the constructor is
|
111 |
* private to prevent instantiation of this class. Use <code>getInstance()</code>
|
112 |
* to obtain an instance for use.
|
113 |
* <br><br>
|
114 |
* For more information about the 'Singleton' pattern I highly recommend
|
115 |
* the book Design Patterns by Gamma, Helm, Johnson and Vlissides
|
116 |
* ISBN 0-201-63361-2.
|
117 |
*/
|
118 |
/*--------------------------------------------------------------------------*/
|
119 |
private Librarian ()
|
120 |
{ |
121 |
Housekeeper.getInstance ().registerForCleanup (this);
|
122 |
extension = '.' + TargetFactory.getInstance ().getNativeLibraryExtension ();
|
123 |
} |
124 |
/*--------------------------------------------------------------------------*/
|
125 |
/**
|
126 |
* Returns an instance of <code>Librarian</code> to use.
|
127 |
*
|
128 |
* @return an instance of <code>Librarian</code>.
|
129 |
*/
|
130 |
/*--------------------------------------------------------------------------*/
|
131 |
public static Librarian getInstance () |
132 |
{ |
133 |
if (me == null) |
134 |
{ |
135 |
me = new Librarian ();
|
136 |
} |
137 |
|
138 |
return (me);
|
139 |
} |
140 |
/*--------------------------------------------------------------------------*/
|
141 |
/**
|
142 |
* Loads the requested library. If the library is already loaded, this
|
143 |
* method returns immediately, without an attempt to load the library again.
|
144 |
* <br><br>
|
145 |
* <b>Invocation Example:</b>
|
146 |
* This assumes that the call is made from the class that links with the
|
147 |
* library. If this is not the case, <code>this</code> must be replaced by
|
148 |
* the reference of the class that links with the library.
|
149 |
* <br><br><code>
|
150 |
* Librarian.getInstance ().loadLibrary ("MyLibrary", this);
|
151 |
* </code>
|
152 |
* <br><br>
|
153 |
* Loading of a native library file works as follows:<br>
|
154 |
* <ul>
|
155 |
* <li>If the library is already loaded there is nothing to do.
|
156 |
* <li>An attempt is made to load the library by its name. If there is no
|
157 |
* system path set to the library, this attempt will fail.
|
158 |
* <li>If the client is located on the local file system, an attempt is
|
159 |
* made to load the library from the local files system as well.
|
160 |
* <li>If the library is located inside a *.jar file, it is extracted to
|
161 |
* 'java.io.tmpdir' and an attempt is made to load it from there.
|
162 |
* </ul>
|
163 |
* <br><br>
|
164 |
* Loading from the local file system and from the *.jar file is attempted
|
165 |
* for the following potential locations of the library in this order:<br>
|
166 |
* <ol>
|
167 |
* <li>The same directory where the client is located
|
168 |
* <li>The native library directory
|
169 |
* </ol>
|
170 |
*
|
171 |
* @param name the name of the library. A file extension and path
|
172 |
* are not needed, in fact if supplied, both is
|
173 |
* stripped off. A specific extension is
|
174 |
* appended.
|
175 |
* @param client the object that made the load request
|
176 |
*
|
177 |
* @see #setNativeDirectory
|
178 |
*
|
179 |
* @exception Exception if all attempts to load the library fail.
|
180 |
*/
|
181 |
/*--------------------------------------------------------------------------*/
|
182 |
public synchronized void loadLibrary (String name, |
183 |
NativeLibraryClient client) throws Exception |
184 |
{ |
185 |
String libraryName = strip (name);
|
186 |
String tempFileName = ""; |
187 |
|
188 |
// ----------------------------------------------------
|
189 |
// Return if the library is already loaded
|
190 |
// ----------------------------------------------------
|
191 |
if (loaded (libraryName))
|
192 |
{ |
193 |
return;
|
194 |
} |
195 |
|
196 |
// ----------------------------------------------------
|
197 |
// First try a straight load
|
198 |
// ----------------------------------------------------
|
199 |
try
|
200 |
{ |
201 |
System.loadLibrary (libraryName);
|
202 |
return;
|
203 |
} |
204 |
catch (UnsatisfiedLinkError exception) {} |
205 |
catch (SecurityException exception) {} |
206 |
|
207 |
// ----------------------------------------------------
|
208 |
// Next, try to get the protocol for loading the resource.
|
209 |
// ----------------------------------------------------
|
210 |
Class clientClass = client.getClass ();
|
211 |
String resourceName = clientClass.getName ();
|
212 |
int nameStart = resourceName.lastIndexOf ('.') + 1; |
213 |
resourceName = resourceName.substring (nameStart, resourceName.length ()) + CLIENT_EXTENSION; |
214 |
URL url = clientClass.getResource (resourceName);
|
215 |
if (url == null) |
216 |
{ |
217 |
throw (new Exception ("can't identify load protocol for " + libraryName + extension)); |
218 |
} |
219 |
String protocol = url.getProtocol ();
|
220 |
|
221 |
// ----------------------------------------------------
|
222 |
// If it's a local file, load it from the current location
|
223 |
// ----------------------------------------------------
|
224 |
if (protocol.equalsIgnoreCase (FILE_PROTOCOL))
|
225 |
{ |
226 |
try
|
227 |
{ |
228 |
System.load (getClientPath (name, url));
|
229 |
} |
230 |
catch (Throwable exception) |
231 |
{ |
232 |
try
|
233 |
{ |
234 |
System.load (getNativePath (name, client));
|
235 |
} |
236 |
catch (Throwable exception2) |
237 |
{ |
238 |
throw (new Exception ("error loading library")); |
239 |
} |
240 |
} |
241 |
} |
242 |
|
243 |
// ----------------------------------------------------
|
244 |
// If it is in a *.jar file, extract it to 'java.io.tmpdir'
|
245 |
// ----------------------------------------------------
|
246 |
|
247 |
else if (protocol.equalsIgnoreCase (JAR_PROTOCOL)) |
248 |
{ |
249 |
tempFileName = getTempFileName (libraryName); |
250 |
try
|
251 |
{ |
252 |
extractFromJar (libraryName, tempFileName, client); |
253 |
|
254 |
clients.add (client); |
255 |
temporaryFileNames.add (tempFileName); |
256 |
libraryNames.add (tempFileName.substring ((tempFileName.lastIndexOf (File.separatorChar) + 1), tempFileName.length ())); |
257 |
|
258 |
// --------------------------------------------------
|
259 |
// Try loading the temporary file from 'java.io.tmpdir'.
|
260 |
// --------------------------------------------------
|
261 |
System.load (tempFileName);
|
262 |
} |
263 |
catch (Throwable exception) |
264 |
{ |
265 |
throw (new Exception ("error loading library\n" + exception.toString ())); |
266 |
} |
267 |
} |
268 |
} |
269 |
/*--------------------------------------------------------------------------*/
|
270 |
/**
|
271 |
* Verifies if the library has already been loaded and keeps track of all
|
272 |
* libraries that are verified.
|
273 |
*
|
274 |
* @param name name of the library to verify
|
275 |
*
|
276 |
* @return <code>true</code> if the library had already been loaded,
|
277 |
* otherwise <code>false</code>.
|
278 |
*/
|
279 |
/*--------------------------------------------------------------------------*/
|
280 |
private boolean loaded (String name) |
281 |
{ |
282 |
if (trackList.contains (name))
|
283 |
{ |
284 |
return (true); |
285 |
} |
286 |
else
|
287 |
{ |
288 |
trackList.add (name); |
289 |
return (false); |
290 |
} |
291 |
} |
292 |
/*--------------------------------------------------------------------------*/
|
293 |
/**
|
294 |
* Strips the extension of the library name, if it has one.
|
295 |
*
|
296 |
* @param name the name of the library
|
297 |
*
|
298 |
* @return the name without an extension
|
299 |
*/
|
300 |
/*--------------------------------------------------------------------------*/
|
301 |
private String strip (String name) |
302 |
{ |
303 |
int extensionStart = name.lastIndexOf ('.'); |
304 |
int nameStart = name.lastIndexOf ('/'); |
305 |
if (nameStart < 0) |
306 |
{ |
307 |
nameStart = name.lastIndexOf ('\\');
|
308 |
} |
309 |
nameStart++; |
310 |
|
311 |
String shortName;
|
312 |
|
313 |
if (extensionStart > 0) |
314 |
{ |
315 |
shortName = name.substring (nameStart, extensionStart); |
316 |
} |
317 |
else
|
318 |
{ |
319 |
shortName = name.substring (nameStart, name.length ()); |
320 |
} |
321 |
|
322 |
return (shortName);
|
323 |
} |
324 |
/*--------------------------------------------------------------------------*/
|
325 |
/**
|
326 |
* Makes an attempt to extract the named library from the jar file and to
|
327 |
* store it on the local file system for temporary use. If the attempt is
|
328 |
* successful, the fully qualified file name of the library on the local
|
329 |
* file system is returned.
|
330 |
*
|
331 |
* @param name the simple name of the library
|
332 |
* @param destination the fully qualified name of the destination file.
|
333 |
* @param client the class that made the load request.
|
334 |
*
|
335 |
* @exception Exception if the library can not be extracted from
|
336 |
* the *.jar file.
|
337 |
* @exception FileNotFoundException if the *.jar file does not exist. The
|
338 |
* way things operate here, this should
|
339 |
* actually never happen.
|
340 |
*/
|
341 |
/*--------------------------------------------------------------------------*/
|
342 |
private void extractFromJar (String name, |
343 |
String destination,
|
344 |
NativeLibraryClient client) throws Exception |
345 |
{ |
346 |
int bytesRead = 0; |
347 |
OutputStream output = null; |
348 |
|
349 |
// ----------------------------------------------------
|
350 |
// open an input stream for the library file
|
351 |
// ----------------------------------------------------
|
352 |
InputStream input = openInputStream (name, client);
|
353 |
|
354 |
// ----------------------------------------------------
|
355 |
// open an output stream for the temporary file
|
356 |
// ----------------------------------------------------
|
357 |
try
|
358 |
{ |
359 |
output = new FileOutputStream (destination); |
360 |
} |
361 |
catch (FileNotFoundException exception) |
362 |
{ |
363 |
input.close (); |
364 |
throw (new Exception ("can't create destination file")); |
365 |
} |
366 |
catch (SecurityException exception) |
367 |
{ |
368 |
input.close (); |
369 |
throw (new Exception ("creation of destination file denied")); |
370 |
} |
371 |
catch (Throwable exception) |
372 |
{ |
373 |
input.close (); |
374 |
throw (new Exception ("unknown problem creating destination file\n" + exception.toString ())); |
375 |
} |
376 |
|
377 |
// ----------------------------------------------------
|
378 |
// pump the data
|
379 |
// ----------------------------------------------------
|
380 |
byte [] buffer = new byte [BLOCK_SIZE]; |
381 |
try
|
382 |
{ |
383 |
do
|
384 |
{ |
385 |
bytesRead = input.read (buffer); |
386 |
if (bytesRead > 0) |
387 |
{ |
388 |
output.write (buffer, 0, bytesRead);
|
389 |
} |
390 |
} |
391 |
while (bytesRead > 0); |
392 |
} |
393 |
catch (Throwable exception) |
394 |
{ |
395 |
throw (new Exception ("error writing to destination file\n" + exception.toString ())); |
396 |
} |
397 |
|
398 |
// ----------------------------------------------------
|
399 |
// flush the data and close both streams
|
400 |
// ----------------------------------------------------
|
401 |
finally
|
402 |
{ |
403 |
input.close (); |
404 |
output.flush (); |
405 |
output.close (); |
406 |
} |
407 |
} |
408 |
/*--------------------------------------------------------------------------*/
|
409 |
/**
|
410 |
* Returns the complete path (including file name) for the native library,
|
411 |
* assuming the native library is located in the same directory from which
|
412 |
* the client was loaded.
|
413 |
*
|
414 |
* @param name the simple name of the library
|
415 |
* @param clientURL a URL that points to the client class
|
416 |
*
|
417 |
* @return the path to the client
|
418 |
*/
|
419 |
/*--------------------------------------------------------------------------*/
|
420 |
private String getClientPath (String name, |
421 |
URL clientURL)
|
422 |
{ |
423 |
String path = clientURL.getFile ();
|
424 |
|
425 |
int nameStart = path.lastIndexOf ('/') + 1; |
426 |
|
427 |
path = path.substring (0, nameStart);
|
428 |
path = path + name + extension; |
429 |
path = path.replace ('/', File.separatorChar); |
430 |
// Revise the URI-path to a file path; needed in uninstaller because it
|
431 |
// writes the jar contents into a sandbox; may be with blanks in the path.
|
432 |
path = revisePath(path); |
433 |
|
434 |
return (path);
|
435 |
} |
436 |
/*--------------------------------------------------------------------------*/
|
437 |
/**
|
438 |
* Returns the complete path (including file name) for the native library,
|
439 |
* assuming the native library is located in a directory where native
|
440 |
* libraries are ordinarily expected.
|
441 |
*
|
442 |
* @param name the simple name of the library
|
443 |
* @param client the class that made the load request.
|
444 |
*
|
445 |
* @return the path to the location of the native libraries.
|
446 |
*/
|
447 |
/*--------------------------------------------------------------------------*/
|
448 |
private String getNativePath (String name, |
449 |
NativeLibraryClient client) |
450 |
{ |
451 |
ProtectionDomain domain = client.getClass ().getProtectionDomain ();
|
452 |
CodeSource codeSource = domain.getCodeSource ();
|
453 |
URL url = codeSource.getLocation ();
|
454 |
String path = url.getPath ();
|
455 |
path = path + nativeDirectory + '/' + name + extension;
|
456 |
path = path.replace ('/', File.separatorChar); |
457 |
// Revise the URI-path to a file path; needed in uninstaller because it
|
458 |
// writes the jar contents into a sandbox; may be with blanks in the path.
|
459 |
path = revisePath(path); |
460 |
|
461 |
return (path);
|
462 |
} |
463 |
/*--------------------------------------------------------------------------*/
|
464 |
/**
|
465 |
* Revises the given path to a file compatible path.
|
466 |
* In fact this method replaces URI-like entries with it chars
|
467 |
* (e.g. %20 with a space).
|
468 |
* @param in path to be revised
|
469 |
* @return revised path
|
470 |
*/
|
471 |
/*--------------------------------------------------------------------------*/
|
472 |
private String revisePath( String in ) |
473 |
{ |
474 |
// This was "stolen" from com.izforge.izpack.util.SelfModifier
|
475 |
|
476 |
StringBuffer sb = new StringBuffer(); |
477 |
CharacterIterator iter = new StringCharacterIterator(in); |
478 |
for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) |
479 |
{ |
480 |
if (c == '%') |
481 |
{ |
482 |
char c1 = iter.next();
|
483 |
if (c1 != CharacterIterator.DONE) |
484 |
{ |
485 |
int i1 = Character.digit(c1, 16); |
486 |
char c2 = iter.next();
|
487 |
if (c2 != CharacterIterator.DONE) |
488 |
{ |
489 |
int i2 = Character.digit(c2, 16); |
490 |
sb.append((char) ((i1 << 4) + i2)); |
491 |
} |
492 |
} |
493 |
} else
|
494 |
{ |
495 |
sb.append(c); |
496 |
} |
497 |
} |
498 |
String path = sb.toString();
|
499 |
return path;
|
500 |
} |
501 |
/*--------------------------------------------------------------------------*/
|
502 |
/**
|
503 |
* Opens an <code>InputStream</code> to the native library.
|
504 |
*
|
505 |
* @param name the simple name of the library
|
506 |
* @param client the class that made the load request.
|
507 |
*
|
508 |
* @return an <code>InputStream</code> from which the library can be read.
|
509 |
*
|
510 |
* @exception Exception if the library can not be located.
|
511 |
*/
|
512 |
/*--------------------------------------------------------------------------*/
|
513 |
private InputStream openInputStream (String name, |
514 |
NativeLibraryClient client) throws Exception |
515 |
{ |
516 |
Class clientClass = client.getClass ();
|
517 |
// ----------------------------------------------------
|
518 |
// try to open an input stream, assuming the library
|
519 |
// is located with the client
|
520 |
// ----------------------------------------------------
|
521 |
InputStream input = clientClass.getResourceAsStream (name + extension);
|
522 |
|
523 |
// ----------------------------------------------------
|
524 |
// if this is not successful, try to load from the
|
525 |
// location where all native libraries are supposed
|
526 |
// to be located.
|
527 |
// ----------------------------------------------------
|
528 |
if (input == null) |
529 |
{ |
530 |
input = clientClass.getResourceAsStream ('/' + nativeDirectory + '/' + name + extension); |
531 |
} |
532 |
|
533 |
// ----------------------------------------------------
|
534 |
// if this fails as well, throw an exception
|
535 |
// ----------------------------------------------------
|
536 |
if (input == null) |
537 |
{ |
538 |
throw (new Exception ("can't locate library")); |
539 |
} |
540 |
else
|
541 |
{ |
542 |
return (input);
|
543 |
} |
544 |
} |
545 |
/*--------------------------------------------------------------------------*/
|
546 |
/**
|
547 |
* Builds a temporary file name for the native library.
|
548 |
*
|
549 |
* @param name the file name of the library
|
550 |
*
|
551 |
* @return a fully qualified file name that can be used to store the file
|
552 |
* on the local file system.
|
553 |
*/
|
554 |
/*--------------------------------------------------------------------------*/
|
555 |
/*$
|
556 |
* @design
|
557 |
*
|
558 |
* Avoid overwriting any existing files on the user's system. If by some
|
559 |
* remote chance a file by the same name should exist on the user's system,
|
560 |
* modify the temporary file name until a version is found that is unique
|
561 |
* on the system and thus won't interfere.
|
562 |
*--------------------------------------------------------------------------*/
|
563 |
private String getTempFileName (String name) |
564 |
{ |
565 |
StringBuffer fileName = new StringBuffer (); |
566 |
String path = System.getProperty (TEMP_LOCATION_KEY); |
567 |
if (path.charAt (path.length () - 1) == File.separatorChar) |
568 |
{ |
569 |
path = path.substring (0, (path.length () - 1)); |
570 |
} |
571 |
String modifier = ""; |
572 |
int counter = 0; |
573 |
File file = null; |
574 |
|
575 |
do
|
576 |
{ |
577 |
fileName.delete (0, fileName.length ());
|
578 |
fileName.append (path); |
579 |
fileName.append (File.separatorChar);
|
580 |
fileName.append (name); |
581 |
fileName.append (modifier); |
582 |
fileName.append (extension); |
583 |
|
584 |
modifier = Integer.toString (counter);
|
585 |
counter++; |
586 |
|
587 |
file = new File (fileName.toString ()); |
588 |
} |
589 |
while (file.exists ());
|
590 |
|
591 |
return (fileName.toString ());
|
592 |
} |
593 |
/*--------------------------------------------------------------------------*/
|
594 |
/**
|
595 |
* Sets the directory where <code>Librarian</code> will search for native
|
596 |
* files. Directories are denoted relative to the root, where the root is
|
597 |
* the same location where the top level Java package directory is located
|
598 |
* (usually called <code>com</code>). The default directory is
|
599 |
* <code>native</code>.
|
600 |
*
|
601 |
* @param directory the directory where native files are located.
|
602 |
*/
|
603 |
/*--------------------------------------------------------------------------*/
|
604 |
public void setNativeDirectory (String directory) |
605 |
{ |
606 |
if (directory == null) |
607 |
{ |
608 |
nativeDirectory = "";
|
609 |
} |
610 |
else
|
611 |
{ |
612 |
nativeDirectory = directory; |
613 |
} |
614 |
} |
615 |
/*--------------------------------------------------------------------------*/
|
616 |
/**
|
617 |
* This method attempts to remove all native libraries that have been
|
618 |
* temporarily created from the system.
|
619 |
*/
|
620 |
/*--------------------------------------------------------------------------*/
|
621 |
public void cleanUp () |
622 |
{ |
623 |
for (int i = 0; i < clients.size (); i++) |
624 |
{ |
625 |
// --------------------------------------------------
|
626 |
// free the library
|
627 |
// --------------------------------------------------
|
628 |
NativeLibraryClient client = (NativeLibraryClient)clients.elementAt (i); |
629 |
String libraryName = (String)libraryNames.elementAt (i); |
630 |
|
631 |
FreeThread free = new FreeThread (libraryName, client);
|
632 |
free.start (); |
633 |
try
|
634 |
{ |
635 |
// give the thread some time to get the library
|
636 |
// freed before attempting to delete it.
|
637 |
free.join (50);
|
638 |
} |
639 |
catch (Throwable exception) {} // nothing I can do |
640 |
|
641 |
// --------------------------------------------------
|
642 |
// delete the library
|
643 |
// --------------------------------------------------
|
644 |
String tempFileName = (String)temporaryFileNames.elementAt (i); |
645 |
try
|
646 |
{ |
647 |
File file = new File (tempFileName); |
648 |
file.delete (); |
649 |
} |
650 |
catch (Throwable exception) {} // nothing I can do |
651 |
} |
652 |
} |
653 |
} |
654 |
/*---------------------------------------------------------------------------*/
|