diff --git a/README.md b/README.md
index e0596ec..578603c 100644
--- a/README.md
+++ b/README.md
@@ -17,13 +17,13 @@ task { "world" } and task { "Hello" } success {
Please refer to the [Kovenant](http://kovenant.komponents.nl) site for API usage and more.
## Getting started
-Build against Kotlin: `1.0.1`.
+Build against Kotlin: `1.0.1-1`.
Source and target compatibility is `1.6`
###Gradle
```groovy
dependencies {
- compile 'nl.komponents.kovenant:kovenant:3.2.0'
+ compile 'nl.komponents.kovenant:kovenant:3.2.1'
}
```
@@ -32,7 +32,7 @@ dependencies {
nl.komponents.kovenant
kovenant
- 3.2.0
+ 3.2.1
```
diff --git a/build.gradle b/build.gradle
index f8f0a03..af9ce96 100644
--- a/build.gradle
+++ b/build.gradle
@@ -20,7 +20,7 @@
*/
buildscript {
- ext.kotlinVersion = '1.0.1'
+ ext.kotlinVersion = '1.0.1-1'
ext.extraConfVersion = '2.2.+'
repositories {
@@ -39,7 +39,7 @@ buildscript {
allprojects {
ext {
- appVersion = '3.2.0'
+ appVersion = '3.2.1'
appGroup = 'nl.komponents.kovenant'
diff --git a/docs/docs/changelog.md b/docs/docs/changelog.md
index a2315b6..81068e0 100644
--- a/docs/docs/changelog.md
+++ b/docs/docs/changelog.md
@@ -3,6 +3,12 @@
Changelog of Kovenant. Complying to [Semantic Versioning](http://semver.org).
Please refer to [roadmap](roadmap.md) for upcoming releases.
+##v3.2.1
+
+**core**
+
+* [KOV-78](http://issues.komponents.nl/youtrack/issue/KOV-78) Support android with api level set to 15
+
##v3.2.0
**core**
diff --git a/docs/docs/index.md b/docs/docs/index.md
index 7d8492a..cfa8180 100644
--- a/docs/docs/index.md
+++ b/docs/docs/index.md
@@ -25,13 +25,13 @@ Developed with the following [goals](misc/goals.md) in mind.
* **Dependency free**: when not counting kotlin std
## Getting started
-Build against Kotlin: `1.0.1`.
+Build against Kotlin: `1.0.1-1`.
Source and target compatibility is `1.6`
###Gradle
```groovy
dependencies {
- compile 'nl.komponents.kovenant:kovenant:3.2.0'
+ compile 'nl.komponents.kovenant:kovenant:3.2.1'
}
```
@@ -40,7 +40,7 @@ dependencies {
nl.komponents.kovenant
kovenant
- 3.2.0
+ 3.2.1
```
diff --git a/projects/core/src/main/kotlin/cas-jvm.kt b/projects/core/src/main/kotlin/cas-jvm.kt
index ebcf3c2..f835306 100644
--- a/projects/core/src/main/kotlin/cas-jvm.kt
+++ b/projects/core/src/main/kotlin/cas-jvm.kt
@@ -1,6 +1,26 @@
+/*
+ * Copyright (c) 2016 Mark Platvoet
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * THE SOFTWARE.
+ */
+
package nl.komponents.kovenant.unsafe
-import sun.misc.Unsafe
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater
import kotlin.reflect.KClass
@@ -29,23 +49,54 @@ class UnsafeAtomicReferenceFieldUpdater(targetClass: KClass
override fun weakCompareAndSet(target: C, expected: V?, update: V?): Boolean = compareAndSet(target, expected, update)
}
+private val noUnsafeMarker = Any()
+private @Volatile var unsafeInstance: Any? = null
fun hasUnsafe(): Boolean {
- try {
- Class.forName("sun.misc.Unsafe")
- return true
- } catch(e: ClassNotFoundException) {
- return false
+ if (unsafeInstance == null) {
+ loadUnsafe()
}
+ return unsafeInstance != noUnsafeMarker
}
-private fun getUnsafe(): Unsafe {
+private fun loadUnsafe() {
try {
- val field = Unsafe::class.java.getDeclaredField("theUnsafe");
- field.isAccessible = true;
- return field.get(null) as Unsafe;
+ val clazz = Class.forName("sun.misc.Unsafe")
+
+ clazz.tryGetStaticField("theUnsafe") {
+ unsafeInstance = it ?: noUnsafeMarker
+ return
+ }
+
+ //KOV-78: Name on old dalvik implementations
+ clazz.tryGetStaticField("THE_ONE") {
+ unsafeInstance = it ?: noUnsafeMarker
+ return
+ }
+ } catch(e: Exception) {
+ //ignore
+ }
+ unsafeInstance = noUnsafeMarker
+}
+private inline fun Class<*>.tryGetStaticField(name: String, onFound: (Any?) -> Unit) {
+ try {
+ val field = getDeclaredField(name)
+ field.isAccessible = true
+ val fieldValue = field.get(null)
+ onFound(fieldValue)
} catch (e: Exception) {
- throw RuntimeException("unsafe doesn't exist or is not accessible")
+ //ignore
+ }
+}
+
+private fun getUnsafe(): sun.misc.Unsafe {
+ if (unsafeInstance == null) {
+ loadUnsafe()
+ }
+ if (unsafeInstance != noUnsafeMarker) {
+ return unsafeInstance as sun.misc.Unsafe
}
+
+ throw RuntimeException("unsafe doesn't exist or is not accessible")
}
\ No newline at end of file
diff --git a/projects/rx/rx.gradle b/projects/rx/rx.gradle
index a1d8fdc..09cdc54 100644
--- a/projects/rx/rx.gradle
+++ b/projects/rx/rx.gradle
@@ -24,5 +24,5 @@ project.description = "Add Promise support to Rx"
dependencies {
compile project(':kovenant-core')
- compile 'io.reactivex:rxjava:1.1.1'
+ compile 'io.reactivex:rxjava:1.1.2'
}
\ No newline at end of file