annotate src/name/blackcap/exifwasher/exiv2/Initialize.kt @ 12:9ac6136c710c

Replace the temporary error handling in Initialize.kt.
author David Barts <n5jrn@me.com>
date Fri, 10 Apr 2020 23:22:36 -0700
parents efd9fe2d70d7
children cd2ca4727b7f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
1 /*
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
2 * Logic common to initializing all external (JNI) classes goes here.
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
3 */
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
4 package name.blackcap.exifwasher.exiv2
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
5
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
6 import java.io.File
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
7 import java.io.FileOutputStream
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
8 import java.io.IOException
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
9 import java.util.jar.JarEntry
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
10 import java.util.jar.JarFile
12
9ac6136c710c Replace the temporary error handling in Initialize.kt.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
11 import java.util.logging.Level
9ac6136c710c Replace the temporary error handling in Initialize.kt.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
12 import java.util.logging.Logger
9ac6136c710c Replace the temporary error handling in Initialize.kt.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
13 import javax.swing.*
9ac6136c710c Replace the temporary error handling in Initialize.kt.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
14 import name.blackcap.exifwasher.Application
0
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
15 import name.blackcap.exifwasher.LF_DIR
12
9ac6136c710c Replace the temporary error handling in Initialize.kt.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
16 import name.blackcap.exifwasher.LOGGER
0
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
17 import name.blackcap.exifwasher.OS
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
18
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
19 object Initialize {
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
20 private var initialized = false
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
21
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
22 public fun libraries() {
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
23 /* no-op if already initialized */
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
24 if (initialized) {
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
25 return
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
26 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
27
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
28 /* use the appropriate binary for the system we're on */
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
29 val subdir = when(OS.type) {
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
30 OS.UNIX -> "linux"
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
31 OS.MAC -> "mac"
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
32 OS.WINDOWS -> "windows"
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
33 OS.OTHER -> throw RuntimeException("unsupported OS!")
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
34 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
35 val ext = when(OS.type) {
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
36 OS.UNIX -> "so"
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
37 OS.MAC -> "dylib"
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
38 OS.WINDOWS -> "dll"
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
39 OS.OTHER -> throw RuntimeException("unsupported OS!")
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
40 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
41
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
42 /* extract to scratch files, if needed, then load */
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
43 val klass = Initialize::class.java
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
44 var myJar = JarFile(File(klass.getProtectionDomain().getCodeSource().getLocation().toURI()))
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
45 for (base in arrayOf("libexiv2", "libjni")) {
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
46 val eBase = "${base}.${ext}"
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
47 val sPath = "name/blackcap/exifwasher/binaries/${subdir}/${eBase}"
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
48 val source = myJar.getJarEntry(sPath)
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
49 if (source == null) {
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
50 die("${sPath} not found in jar")
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
51 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
52 val target = File(LF_DIR, eBase)
1
42277ce58ace Improve exception handling; always use absolute paths on libs.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
53 val tPath = target.absolutePath
0
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
54 try {
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
55 if (!target.exists() || target.lastModified() < source.getTime()) {
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
56 myJar.getInputStream(source).use { sfp ->
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
57 FileOutputStream(target).use { tfp ->
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
58 sfp.copyTo(tfp)
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
59 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
60 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
61 target.setExecutable(true)
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
62 target.setLastModified(source.getTime())
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
63 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
64 } catch (e: IOException) {
12
9ac6136c710c Replace the temporary error handling in Initialize.kt.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
65 LOGGER.log(Level.SEVERE, "unable to create ${tPath}", e)
0
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
66 val message = e.message ?: "I/O error"
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
67 die("unable to create ${tPath}: ${message}")
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
68 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
69 try {
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
70 System.load(tPath)
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
71 } catch (e: UnsatisfiedLinkError) {
12
9ac6136c710c Replace the temporary error handling in Initialize.kt.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
72 LOGGER.log(Level.SEVERE, "unable to link ${tPath}", e)
0
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
73 val message = e.message ?: "unsatisfied link"
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
74 die("unable to link ${tPath}: ${message}")
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
75 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
76 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
77
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
78 initialized = true
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
79 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
80
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
81 private fun die(message: String) {
12
9ac6136c710c Replace the temporary error handling in Initialize.kt.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
82 JOptionPane.showMessageDialog(Application.mainFrame,
9ac6136c710c Replace the temporary error handling in Initialize.kt.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
83 "A fatal error occurred in initialization:\n${message}",
9ac6136c710c Replace the temporary error handling in Initialize.kt.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
84 "Error", JOptionPane.ERROR_MESSAGE)
9ac6136c710c Replace the temporary error handling in Initialize.kt.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
85 LOGGER.log(Level.SEVERE, "aborted due to fatal error")
0
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
86 System.exit(1)
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
87 }
db63d01a23c6 JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff changeset
88 }