diff --git a/README.asciidoc b/README.asciidoc
index 43d8f64d..041daed8 100644
--- a/README.asciidoc
+++ b/README.asciidoc
@@ -1,30 +1,55 @@
Java EE 8 Samples
-=================
+-----------------
+Covered JSRs
+~~~~~~~~~~~~
+* JSR 365: CDI 2.0
+* JSR 107: JCACHE
+* JSR 367: JSON-B
-. Download http://download.jboss.org/wildfly/8.2.0.Final/wildfly-8.2.0.Final.zip[WildFly 8.2.0] and unzip
-. Download Weld3 Alpha 3
+Running the tests
+~~~~~~~~~~~~~~~~~
+. Download WildFly 10.1 and unzip it
+
[source, text]
----
-curl -L -o weld3-alpha3-patch-wildfly8.2.zip http://sourceforge.net/projects/jboss/files/Weld/3.0.0.Alpha3/wildfly-8.2.0.Final-weld-3.0.0.Alpha3-patch.zip/download
+curl -L http://download.jboss.org/wildfly/10.1.0.Final/wildfly-10.1.0.Final.zip -o wildfly-10.1.0.Final.zip
+----
+. Download Weld 3.0.0.CR1 as a patch for WildFly 10.1
++
+[source, text]
+----
+curl -L http://download.jboss.org/weld/3.0.0.CR1/wildfly-10.1.0.Final-weld-3.0.0.CR1-patch.zip -o wildfly-10.1.0.Final-weld-3.0.0.CR1-patch.zip
----
+
. Apply the patch
+
[source, text]
----
-./wildfly-8.2.0.Final/bin/jboss-cli.sh --command="patch apply ./weld3-alpha3-patch-wildfly8.2.zip"
+./wildfly-10.1.0.Final/bin/jboss-cli.sh --command="patch apply ./wildfly-10.1.0.Final-weld-3.0.0.CR1-patch.zip"
{
"outcome" : "success",
"result" : {}
}
----
+
+. Download Infinispan 9.0.0.Beta2 packaged modules for deploying in WildFly
++
+[source, text]
+----
+curl -L http://downloads.jboss.org/infinispan/9.0.0.Beta2/infinispan-wildfly-modules-9.0.0.Beta2.zip -o infinispan-wildfly-modules-9.0.0.Beta2.zip
+----
+. Unzip and copy modules
++
+[source, text]
+----
+unzip ./infinispan-wildfly-modules-9.0.0.Beta2.zip -d ./wildfly-10.1.0.Final/modules
+----
++
. Start WildFly
+
[source, text]
----
-./wildfly-8.2.0.Final/bin/standalone.sh
+./wildfly-10.1.0.Final/bin/standalone.sh
----
+
. Run tests
diff --git a/cdi/events-priority/src/main/java/org/javaee8/cdi/events/priority/GreetingReceiver.java b/cdi/events-priority/src/main/java/org/javaee8/cdi/events/priority/GreetingReceiver.java
index 94941cc2..6a5849af 100644
--- a/cdi/events-priority/src/main/java/org/javaee8/cdi/events/priority/GreetingReceiver.java
+++ b/cdi/events-priority/src/main/java/org/javaee8/cdi/events/priority/GreetingReceiver.java
@@ -1,34 +1,44 @@
package org.javaee8.cdi.events.priority;
-import javax.enterprise.context.SessionScoped;
+import javax.annotation.Priority;
+import javax.enterprise.context.RequestScoped;
import javax.enterprise.event.Observes;
-import java.io.Serializable;
import javax.interceptor.Interceptor;
-import org.jboss.weld.experimental.Priority;
+import java.io.Serializable;
/**
+ * Using {@link javax.annotation.Priority} annotation to define an order in which observer methods are called.
+ * Observers with smaller priority values are called first.
+ *
* @author Radim Hanus
* @author Arun Gupta
+ *
+ * @see relevant chapter in cdi-2.0 spec
*/
-@SessionScoped
+@RequestScoped
public class GreetingReceiver implements EventReceiver, Serializable {
private String greet = "Willkommen";
/**
- * Lower priority
- * @param greet
+ * Higher priority
*/
- void receive(@Observes @Priority(Interceptor.Priority.APPLICATION + 200) String greet) {
- this.greet += greet + "2";
+ void receiveFirst(@Observes @Priority(Interceptor.Priority.APPLICATION) String greet) {
+ this.greet = greet + "First ";
}
/**
- * Higher priority
- * @param greet
+ * Middle priority, uses default priority Interceptor.Priority.APPLICATION + 500
+ */
+ void receiveSecond(@Observes String greet) {
+ this.greet += greet + "Second ";
+ }
+
+ /**
+ * Lower priority
*/
- void receive2(@Observes @Priority(Interceptor.Priority.APPLICATION) String greet) {
- this.greet = greet + "1";
+ void receiveThird(@Observes @Priority(Interceptor.Priority.APPLICATION + 1000) String greet) {
+ this.greet += greet + "Third";
}
@Override
diff --git a/cdi/events-priority/src/test/java/org/javaee8/cdi/events/priority/GreetingTest.java b/cdi/events-priority/src/test/java/org/javaee8/cdi/events/priority/GreetingTest.java
index 45780880..74f21a9c 100644
--- a/cdi/events-priority/src/test/java/org/javaee8/cdi/events/priority/GreetingTest.java
+++ b/cdi/events-priority/src/test/java/org/javaee8/cdi/events/priority/GreetingTest.java
@@ -1,9 +1,5 @@
package org.javaee8.cdi.events.priority;
-import org.javaee8.cdi.events.priority.EventSender;
-import org.javaee8.cdi.events.priority.GreetingSender;
-import org.javaee8.cdi.events.priority.GreetingReceiver;
-import org.javaee8.cdi.events.priority.EventReceiver;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.Archive;
@@ -15,8 +11,6 @@
import javax.inject.Inject;
import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@@ -41,17 +35,14 @@ public static Archive> deploy() {
@Test
public void test() throws Exception {
- assertThat(sender, is(notNullValue()));
assertThat(sender, instanceOf(GreetingSender.class));
-
- assertThat(receiver, is(notNullValue()));
assertThat(receiver, instanceOf(GreetingReceiver.class));
// default greet
assertEquals("Willkommen", receiver.getGreet());
// send a new greet
- sender.send("Welcome");
+ sender.send("Welcome:");
// receiver must not belongs to the dependent pseudo-scope since we are checking the result
- assertEquals("Welcome1Welcome2", receiver.getGreet());
+ assertEquals("Welcome:First Welcome:Second Welcome:Third", receiver.getGreet());
}
}
diff --git a/cdi/events-priority/src/test/resources/beans.xml b/cdi/events-priority/src/test/resources/beans.xml
index aa8e5774..dc8b6e83 100644
--- a/cdi/events-priority/src/test/resources/beans.xml
+++ b/cdi/events-priority/src/test/resources/beans.xml
@@ -1,8 +1,7 @@
-
-
diff --git a/cdi/pom.xml b/cdi/pom.xml
index fb364e1a..fa3d8696 100644
--- a/cdi/pom.xml
+++ b/cdi/pom.xml
@@ -1,6 +1,8 @@
-
+
4.0.0
+
org.javaee8
javaee8-samples
@@ -12,9 +14,10 @@
cdi-samples
1.0-SNAPSHOT
pom
- Java EE 8 CDI Samples
+ JSR 365: CDI 2.0 Samples
events-priority
+
diff --git a/jcache/README.md b/jcache/README.md
new file mode 100644
index 00000000..59c2a961
--- /dev/null
+++ b/jcache/README.md
@@ -0,0 +1,2 @@
+JSR 107: JCACHE Samples
+=======================
\ No newline at end of file
diff --git a/jcache/annotation-cache-put/pom.xml b/jcache/annotation-cache-put/pom.xml
new file mode 100644
index 00000000..5b60c385
--- /dev/null
+++ b/jcache/annotation-cache-put/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ annotation-cache-put
+
diff --git a/jcache/annotation-cache-put/src/main/java/org/javaee8/jcache/annotation/KeyValueService.java b/jcache/annotation-cache-put/src/main/java/org/javaee8/jcache/annotation/KeyValueService.java
new file mode 100644
index 00000000..fe879bca
--- /dev/null
+++ b/jcache/annotation-cache-put/src/main/java/org/javaee8/jcache/annotation/KeyValueService.java
@@ -0,0 +1,22 @@
+package org.javaee8.jcache.annotation;
+
+import javax.cache.annotation.CacheDefaults;
+import javax.cache.annotation.CachePut;
+import javax.cache.annotation.CacheResult;
+import javax.cache.annotation.CacheValue;
+
+
+/**
+ * @author Radim Hanus
+ */
+@CacheDefaults(cacheName = "cache.default")
+public class KeyValueService {
+ @CachePut
+ public void put(K key, @CacheValue V value) {
+ }
+
+ @CacheResult
+ public V get(K key) {
+ return null;
+ }
+}
diff --git a/jcache/annotation-cache-put/src/test/java/org/javaee8/jcache/annotation/KeyValueServiceTest.java b/jcache/annotation-cache-put/src/test/java/org/javaee8/jcache/annotation/KeyValueServiceTest.java
new file mode 100644
index 00000000..6f427a17
--- /dev/null
+++ b/jcache/annotation-cache-put/src/test/java/org/javaee8/jcache/annotation/KeyValueServiceTest.java
@@ -0,0 +1,37 @@
+package org.javaee8.jcache.annotation;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+
+@RunWith(Arquillian.class)
+public class KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class)
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+
+ @Test
+ public void test() throws Exception {
+ assertNull(service.get("JSR107"));
+
+ service.put("JSR107", "JCACHE");
+ assertEquals("JCACHE", service.get("JSR107"));
+ }
+}
diff --git a/jcache/annotation-cache-put/src/test/resources/beans.xml b/jcache/annotation-cache-put/src/test/resources/beans.xml
new file mode 100644
index 00000000..de591c11
--- /dev/null
+++ b/jcache/annotation-cache-put/src/test/resources/beans.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ org.infinispan.jcache.annotation.InjectedCacheResultInterceptor
+ org.infinispan.jcache.annotation.InjectedCachePutInterceptor
+
+
+
diff --git a/jcache/annotation-cache-put/src/test/resources/jboss-deployment-structure.xml b/jcache/annotation-cache-put/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/annotation-cache-put/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/annotation-cache-remove-all/pom.xml b/jcache/annotation-cache-remove-all/pom.xml
new file mode 100644
index 00000000..6afad3e3
--- /dev/null
+++ b/jcache/annotation-cache-remove-all/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ annotation-cache-remove-all
+
diff --git a/jcache/annotation-cache-remove-all/src/main/java/org/javaee8/jcache/annotation/KeyValueService.java b/jcache/annotation-cache-remove-all/src/main/java/org/javaee8/jcache/annotation/KeyValueService.java
new file mode 100644
index 00000000..189033a9
--- /dev/null
+++ b/jcache/annotation-cache-remove-all/src/main/java/org/javaee8/jcache/annotation/KeyValueService.java
@@ -0,0 +1,23 @@
+package org.javaee8.jcache.annotation;
+
+import javax.cache.annotation.*;
+
+
+/**
+ * @author Radim Hanus
+ */
+@CacheDefaults(cacheName = "cache.default")
+public class KeyValueService {
+ @CachePut
+ public void put(K key, @CacheValue V value) {
+ }
+
+ @CacheResult
+ public V get(K key) {
+ return null;
+ }
+
+ @CacheRemoveAll
+ public void deleteAll() {
+ }
+}
diff --git a/jcache/annotation-cache-remove-all/src/test/java/org/javaee8/jcache/annotation/KeyValueServiceTest.java b/jcache/annotation-cache-remove-all/src/test/java/org/javaee8/jcache/annotation/KeyValueServiceTest.java
new file mode 100644
index 00000000..fa197bd2
--- /dev/null
+++ b/jcache/annotation-cache-remove-all/src/test/java/org/javaee8/jcache/annotation/KeyValueServiceTest.java
@@ -0,0 +1,45 @@
+package org.javaee8.jcache.annotation;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+
+@RunWith(Arquillian.class)
+public class KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class)
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+
+ @Test
+ public void test() throws Exception {
+ assertNull(service.get("JSR107"));
+ assertNull(service.get("JSR367"));
+
+ service.put("JSR107", "JCACHE");
+ assertEquals("JCACHE", service.get("JSR107"));
+
+ service.put("JSR367", "JSON-B");
+ assertEquals("JSON-B", service.get("JSR367"));
+
+ service.deleteAll();
+ assertNull(service.get("JSR107"));
+ assertNull(service.get("JSR367"));
+ }
+}
diff --git a/jcache/annotation-cache-remove-all/src/test/resources/beans.xml b/jcache/annotation-cache-remove-all/src/test/resources/beans.xml
new file mode 100644
index 00000000..a57407b9
--- /dev/null
+++ b/jcache/annotation-cache-remove-all/src/test/resources/beans.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ org.infinispan.jcache.annotation.InjectedCacheResultInterceptor
+ org.infinispan.jcache.annotation.InjectedCachePutInterceptor
+ org.infinispan.jcache.annotation.InjectedCacheRemoveEntryInterceptor
+ org.infinispan.jcache.annotation.InjectedCacheRemoveAllInterceptor
+
+
+
diff --git a/jcache/annotation-cache-remove-all/src/test/resources/jboss-deployment-structure.xml b/jcache/annotation-cache-remove-all/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/annotation-cache-remove-all/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/annotation-cache-remove/pom.xml b/jcache/annotation-cache-remove/pom.xml
new file mode 100644
index 00000000..96ba5c60
--- /dev/null
+++ b/jcache/annotation-cache-remove/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ annotation-cache-remove
+
diff --git a/jcache/annotation-cache-remove/src/main/java/org/javaee8/jcache/annotation/KeyValueService.java b/jcache/annotation-cache-remove/src/main/java/org/javaee8/jcache/annotation/KeyValueService.java
new file mode 100644
index 00000000..39dfb130
--- /dev/null
+++ b/jcache/annotation-cache-remove/src/main/java/org/javaee8/jcache/annotation/KeyValueService.java
@@ -0,0 +1,23 @@
+package org.javaee8.jcache.annotation;
+
+import javax.cache.annotation.*;
+
+
+/**
+ * @author Radim Hanus
+ */
+@CacheDefaults(cacheName = "cache.default")
+public class KeyValueService {
+ @CachePut
+ public void put(K key, @CacheValue V value) {
+ }
+
+ @CacheResult
+ public V get(K key) {
+ return null;
+ }
+
+ @CacheRemove
+ public void delete(K key) {
+ }
+}
diff --git a/jcache/annotation-cache-remove/src/test/java/org/javaee8/jcache/annotation/KeyValueServiceTest.java b/jcache/annotation-cache-remove/src/test/java/org/javaee8/jcache/annotation/KeyValueServiceTest.java
new file mode 100644
index 00000000..5e261ad6
--- /dev/null
+++ b/jcache/annotation-cache-remove/src/test/java/org/javaee8/jcache/annotation/KeyValueServiceTest.java
@@ -0,0 +1,40 @@
+package org.javaee8.jcache.annotation;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+
+@RunWith(Arquillian.class)
+public class KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class)
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+
+ @Test
+ public void test() throws Exception {
+ assertNull(service.get("JSR107"));
+
+ service.put("JSR107", "JCACHE");
+ assertEquals("JCACHE", service.get("JSR107"));
+
+ service.delete("JSR107");
+ assertNull(service.get("JSR107"));
+ }
+}
diff --git a/jcache/annotation-cache-remove/src/test/resources/beans.xml b/jcache/annotation-cache-remove/src/test/resources/beans.xml
new file mode 100644
index 00000000..901e5cc0
--- /dev/null
+++ b/jcache/annotation-cache-remove/src/test/resources/beans.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ org.infinispan.jcache.annotation.InjectedCacheResultInterceptor
+ org.infinispan.jcache.annotation.InjectedCachePutInterceptor
+ org.infinispan.jcache.annotation.InjectedCacheRemoveEntryInterceptor
+
+
+
diff --git a/jcache/annotation-cache-remove/src/test/resources/jboss-deployment-structure.xml b/jcache/annotation-cache-remove/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/annotation-cache-remove/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/annotation-cache-result/pom.xml b/jcache/annotation-cache-result/pom.xml
new file mode 100644
index 00000000..745fdec2
--- /dev/null
+++ b/jcache/annotation-cache-result/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ annotation-cache-result
+
diff --git a/jcache/annotation-cache-result/src/main/java/org/javaee8/jcache/annotation/DoubleService.java b/jcache/annotation-cache-result/src/main/java/org/javaee8/jcache/annotation/DoubleService.java
new file mode 100644
index 00000000..21158109
--- /dev/null
+++ b/jcache/annotation-cache-result/src/main/java/org/javaee8/jcache/annotation/DoubleService.java
@@ -0,0 +1,26 @@
+package org.javaee8.jcache.annotation;
+
+import javax.cache.annotation.CacheDefaults;
+import javax.cache.annotation.CacheResult;
+
+
+/**
+ * @author Radim Hanus
+ */
+@CacheDefaults(cacheName = "cache.default")
+public class DoubleService {
+ private int nameCallCount = 0;
+ private int dataCallCount = 0;
+
+ @CacheResult
+ public String getName(String name) {
+ nameCallCount++;
+ return name + "_" + nameCallCount;
+ }
+
+ @CacheResult(cacheName = "cache.data")
+ public String getData(String name) {
+ dataCallCount++;
+ return name + "_data_" + dataCallCount;
+ }
+}
diff --git a/jcache/annotation-cache-result/src/main/java/org/javaee8/jcache/annotation/SingleService.java b/jcache/annotation-cache-result/src/main/java/org/javaee8/jcache/annotation/SingleService.java
new file mode 100644
index 00000000..c7994003
--- /dev/null
+++ b/jcache/annotation-cache-result/src/main/java/org/javaee8/jcache/annotation/SingleService.java
@@ -0,0 +1,17 @@
+package org.javaee8.jcache.annotation;
+
+import javax.cache.annotation.CacheResult;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class SingleService {
+ private int callCount = 0;
+
+ @CacheResult
+ public String getName(String name) {
+ callCount++;
+ return name + "_" + callCount;
+ }
+}
diff --git a/jcache/annotation-cache-result/src/test/java/org/javaee8/jcache/annotation/DoubleServiceTest.java b/jcache/annotation-cache-result/src/test/java/org/javaee8/jcache/annotation/DoubleServiceTest.java
new file mode 100644
index 00000000..5067dce1
--- /dev/null
+++ b/jcache/annotation-cache-result/src/test/java/org/javaee8/jcache/annotation/DoubleServiceTest.java
@@ -0,0 +1,41 @@
+package org.javaee8.jcache.annotation;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+
+
+@RunWith(Arquillian.class)
+public class DoubleServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(DoubleService.class)
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private DoubleService service;
+
+ @Test
+ public void test() throws Exception {
+ assertEquals("Dude_1", service.getName("Dude"));
+ assertEquals("Dude_data_1", service.getData("Dude"));
+ assertEquals("Dude_1", service.getName("Dude"));
+ assertEquals("Dude_data_1", service.getData("Dude"));
+
+ assertEquals("Joe_2", service.getName("Joe"));
+ assertEquals("Joe_data_2", service.getData("Joe"));
+ assertEquals("Joe_2", service.getName("Joe"));
+ assertEquals("Joe_data_2", service.getData("Joe"));
+ }
+}
diff --git a/jcache/annotation-cache-result/src/test/java/org/javaee8/jcache/annotation/SingleServiceTest.java b/jcache/annotation-cache-result/src/test/java/org/javaee8/jcache/annotation/SingleServiceTest.java
new file mode 100644
index 00000000..71fd5814
--- /dev/null
+++ b/jcache/annotation-cache-result/src/test/java/org/javaee8/jcache/annotation/SingleServiceTest.java
@@ -0,0 +1,37 @@
+package org.javaee8.jcache.annotation;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+
+
+@RunWith(Arquillian.class)
+public class SingleServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(SingleService.class)
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private SingleService service;
+
+ @Test
+ public void test() throws Exception {
+ assertEquals("Dude_1", service.getName("Dude"));
+ assertEquals("Dude_1", service.getName("Dude"));
+
+ assertEquals("Joe_2", service.getName("Joe"));
+ assertEquals("Joe_2", service.getName("Joe"));
+ }
+}
diff --git a/jcache/annotation-cache-result/src/test/resources/beans.xml b/jcache/annotation-cache-result/src/test/resources/beans.xml
new file mode 100644
index 00000000..2724af63
--- /dev/null
+++ b/jcache/annotation-cache-result/src/test/resources/beans.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ org.infinispan.jcache.annotation.InjectedCacheResultInterceptor
+
+
+
diff --git a/jcache/annotation-cache-result/src/test/resources/jboss-deployment-structure.xml b/jcache/annotation-cache-result/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/annotation-cache-result/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/configure-cache-expiry/pom.xml b/jcache/configure-cache-expiry/pom.xml
new file mode 100644
index 00000000..953c9d9d
--- /dev/null
+++ b/jcache/configure-cache-expiry/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ configure-cache-expiry
+
diff --git a/jcache/configure-cache-expiry/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java b/jcache/configure-cache-expiry/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java
new file mode 100644
index 00000000..f9e8ce86
--- /dev/null
+++ b/jcache/configure-cache-expiry/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java
@@ -0,0 +1,49 @@
+package org.javaee8.jcache.configuration;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.expiry.AccessedExpiryPolicy;
+import javax.cache.expiry.Duration;
+import javax.cache.spi.CachingProvider;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class KeyValueService {
+ static final long CACHE_TIMEOUT_MS = 100L;
+
+ private CacheManager cacheManager;
+ private Cache cache;
+
+ @PostConstruct
+ void init() {
+ CachingProvider cachingProvider = Caching.getCachingProvider();
+ cacheManager = cachingProvider.getCacheManager();
+
+ MutableConfiguration config = new MutableConfiguration<>();
+
+ // cache entries are supposed to expire if its last access time is older than 100 milliseconds
+ config.setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, CACHE_TIMEOUT_MS)));
+
+ cache = cacheManager.createCache("cache.default", config);
+ }
+
+ @PreDestroy
+ void destroy() {
+ cacheManager.close();
+ }
+
+ public void put(K key, V value) {
+ cache.put(key, value);
+ }
+
+ public V get(K key) {
+ return cache.get(key);
+ }
+}
diff --git a/jcache/configure-cache-expiry/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java b/jcache/configure-cache-expiry/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java
new file mode 100644
index 00000000..7badf09f
--- /dev/null
+++ b/jcache/configure-cache-expiry/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java
@@ -0,0 +1,46 @@
+package org.javaee8.jcache.configuration;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class)
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+
+ @Test
+ public void test() throws Exception {
+ // empty cache
+ assertNull(service.get("JSR107"));
+
+ // available in cache
+ service.put("JSR107", "JCACHE");
+ assertEquals("JCACHE", service.get("JSR107"));
+
+ // removed from cache after access timeout
+ Thread.sleep(KeyValueService.CACHE_TIMEOUT_MS + 1L);
+ assertNull(service.get("JSR107"));
+ }
+}
diff --git a/jcache/configure-cache-expiry/src/test/resources/beans.xml b/jcache/configure-cache-expiry/src/test/resources/beans.xml
new file mode 100644
index 00000000..ae366cab
--- /dev/null
+++ b/jcache/configure-cache-expiry/src/test/resources/beans.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/jcache/configure-cache-expiry/src/test/resources/jboss-deployment-structure.xml b/jcache/configure-cache-expiry/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/configure-cache-expiry/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/configure-cache-filter/pom.xml b/jcache/configure-cache-filter/pom.xml
new file mode 100644
index 00000000..46347682
--- /dev/null
+++ b/jcache/configure-cache-filter/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ configure-cache-filter
+
diff --git a/jcache/configure-cache-filter/src/main/java/org/javaee8/jcache/configuration/KeyValueEntryEventFilter.java b/jcache/configure-cache-filter/src/main/java/org/javaee8/jcache/configuration/KeyValueEntryEventFilter.java
new file mode 100644
index 00000000..5cec711a
--- /dev/null
+++ b/jcache/configure-cache-filter/src/main/java/org/javaee8/jcache/configuration/KeyValueEntryEventFilter.java
@@ -0,0 +1,24 @@
+package org.javaee8.jcache.configuration;
+
+import javax.cache.event.CacheEntryEvent;
+import javax.cache.event.CacheEntryEventFilter;
+import javax.cache.event.CacheEntryListenerException;
+import javax.cache.event.EventType;
+import java.io.Serializable;
+
+
+/**
+ * Every second cache removed event is propagated further into cache listeners.
+ *
+ * @author Radim Hanus
+ */
+public class KeyValueEntryEventFilter implements CacheEntryEventFilter, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private int callCounter = 0;
+
+ @Override
+ public boolean evaluate(CacheEntryEvent extends K, ? extends V> event) throws CacheEntryListenerException {
+ return event.getEventType().equals(EventType.REMOVED) && (++callCounter % 2 == 0);
+ }
+}
diff --git a/jcache/configure-cache-filter/src/main/java/org/javaee8/jcache/configuration/KeyValueEntryRemovedListener.java b/jcache/configure-cache-filter/src/main/java/org/javaee8/jcache/configuration/KeyValueEntryRemovedListener.java
new file mode 100644
index 00000000..3ee7ff1d
--- /dev/null
+++ b/jcache/configure-cache-filter/src/main/java/org/javaee8/jcache/configuration/KeyValueEntryRemovedListener.java
@@ -0,0 +1,28 @@
+package org.javaee8.jcache.configuration;
+
+import javax.cache.Cache;
+import javax.cache.event.CacheEntryEvent;
+import javax.cache.event.CacheEntryListenerException;
+import javax.cache.event.CacheEntryRemovedListener;
+import java.io.Serializable;
+
+
+/**
+ * Removed cache entries are propagated into backup cache.
+ *
+ * @author Radim Hanus
+ */
+public class KeyValueEntryRemovedListener implements CacheEntryRemovedListener, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private Cache backupCache;
+
+ public KeyValueEntryRemovedListener(Cache backupCache) {
+ this.backupCache = backupCache;
+ }
+
+ @Override
+ public void onRemoved(Iterable> cacheEntryEvents) throws CacheEntryListenerException {
+ cacheEntryEvents.forEach((entry) -> backupCache.put(entry.getKey(), entry.getValue()));
+ }
+}
diff --git a/jcache/configure-cache-filter/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java b/jcache/configure-cache-filter/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java
new file mode 100644
index 00000000..b370258d
--- /dev/null
+++ b/jcache/configure-cache-filter/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java
@@ -0,0 +1,62 @@
+package org.javaee8.jcache.configuration;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.configuration.FactoryBuilder;
+import javax.cache.configuration.MutableCacheEntryListenerConfiguration;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.spi.CachingProvider;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class KeyValueService {
+ private CacheManager cacheManager;
+ private Cache primaryCache;
+ private Cache secondaryCache;
+
+ @PostConstruct
+ void init() {
+ CachingProvider cachingProvider = Caching.getCachingProvider();
+ cacheManager = cachingProvider.getCacheManager();
+
+ MutableConfiguration config = new MutableConfiguration<>();
+ secondaryCache = cacheManager.createCache("cache.secondary", config);
+
+ // removed entries are inserted into secondary cache by the listener
+ config.addCacheEntryListenerConfiguration(
+ new MutableCacheEntryListenerConfiguration<>(
+ FactoryBuilder.factoryOf(new KeyValueEntryRemovedListener<>(secondaryCache)),
+ FactoryBuilder.factoryOf(new KeyValueEntryEventFilter<>()),
+ true,
+ true)
+ );
+
+ primaryCache = cacheManager.createCache("cache.primary", config);
+ }
+
+ @PreDestroy
+ void destroy() {
+ cacheManager.close();
+ }
+
+ public void put(K key, V value) {
+ primaryCache.put(key, value);
+ }
+
+ public V get(K key) {
+ return primaryCache.get(key);
+ }
+
+ public V getSecondary(K key) {
+ return secondaryCache.get(key);
+ }
+
+ public void remove(K key) {
+ primaryCache.remove(key);
+ }
+}
diff --git a/jcache/configure-cache-filter/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java b/jcache/configure-cache-filter/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java
new file mode 100644
index 00000000..e5c3622a
--- /dev/null
+++ b/jcache/configure-cache-filter/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java
@@ -0,0 +1,61 @@
+package org.javaee8.jcache.configuration;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class, KeyValueEntryRemovedListener.class, KeyValueEntryEventFilter.class)
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+
+ @Test
+ public void test() throws Exception {
+ // empty both primary ans secondary caches
+ assertNull(service.get("JSR107"));
+ assertNull(service.getSecondary("JSR107"));
+
+ assertNull(service.get("JSR367"));
+ assertNull(service.getSecondary("JSR367"));
+
+ // available only in primary cache
+ service.put("JSR107", "JCACHE");
+ assertEquals("JCACHE", service.get("JSR107"));
+ assertNull(service.getSecondary("JSR107"));
+
+ service.put("JSR367", "JSON-B");
+ assertEquals("JSON-B", service.get("JSR367"));
+ assertNull(service.getSecondary("JSR367"));
+
+ // every second remove call is propagated as put operation on secondary cache
+ service.remove("JSR107");
+ assertNull(service.get("JSR107"));
+ assertNull(service.getSecondary("JSR107"));
+
+ // removed from primary cache, but available in secondary cache
+ service.remove("JSR367");
+ assertNull(service.get("JSR367"));
+ assertEquals("JSON-B", service.getSecondary("JSR367"));
+ }
+}
diff --git a/jcache/configure-cache-filter/src/test/resources/beans.xml b/jcache/configure-cache-filter/src/test/resources/beans.xml
new file mode 100644
index 00000000..ae366cab
--- /dev/null
+++ b/jcache/configure-cache-filter/src/test/resources/beans.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/jcache/configure-cache-filter/src/test/resources/jboss-deployment-structure.xml b/jcache/configure-cache-filter/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/configure-cache-filter/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/configure-cache-listener/pom.xml b/jcache/configure-cache-listener/pom.xml
new file mode 100644
index 00000000..154d3dfc
--- /dev/null
+++ b/jcache/configure-cache-listener/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ configure-cache-listener
+
diff --git a/jcache/configure-cache-listener/src/main/java/org/javaee8/jcache/configuration/KeyValueEntryRemovedListener.java b/jcache/configure-cache-listener/src/main/java/org/javaee8/jcache/configuration/KeyValueEntryRemovedListener.java
new file mode 100644
index 00000000..46469c40
--- /dev/null
+++ b/jcache/configure-cache-listener/src/main/java/org/javaee8/jcache/configuration/KeyValueEntryRemovedListener.java
@@ -0,0 +1,26 @@
+package org.javaee8.jcache.configuration;
+
+import javax.cache.Cache;
+import javax.cache.event.CacheEntryEvent;
+import javax.cache.event.CacheEntryListenerException;
+import javax.cache.event.CacheEntryRemovedListener;
+import java.io.Serializable;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class KeyValueEntryRemovedListener implements CacheEntryRemovedListener, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private Cache removedEntriesCache;
+
+ public KeyValueEntryRemovedListener(Cache removedEntriesCache) {
+ this.removedEntriesCache = removedEntriesCache;
+ }
+
+ @Override
+ public void onRemoved(Iterable> cacheEntryEvents) throws CacheEntryListenerException {
+ cacheEntryEvents.forEach((entry) -> removedEntriesCache.put(entry.getKey(), entry.getValue()));
+ }
+}
diff --git a/jcache/configure-cache-listener/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java b/jcache/configure-cache-listener/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java
new file mode 100644
index 00000000..66af24e3
--- /dev/null
+++ b/jcache/configure-cache-listener/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java
@@ -0,0 +1,62 @@
+package org.javaee8.jcache.configuration;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.configuration.FactoryBuilder;
+import javax.cache.configuration.MutableCacheEntryListenerConfiguration;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.spi.CachingProvider;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class KeyValueService {
+ private CacheManager cacheManager;
+ private Cache primaryCache;
+ private Cache secondaryCache;
+
+ @PostConstruct
+ void init() {
+ CachingProvider cachingProvider = Caching.getCachingProvider();
+ cacheManager = cachingProvider.getCacheManager();
+
+ MutableConfiguration config = new MutableConfiguration<>();
+ secondaryCache = cacheManager.createCache("cache.secondary", config);
+
+ // removed entries are inserted into secondary cache by the listener
+ config.addCacheEntryListenerConfiguration(
+ new MutableCacheEntryListenerConfiguration<>(
+ FactoryBuilder.factoryOf(new KeyValueEntryRemovedListener<>(secondaryCache)),
+ null,
+ true,
+ true)
+ );
+
+ primaryCache = cacheManager.createCache("cache.primary", config);
+ }
+
+ @PreDestroy
+ void destroy() {
+ cacheManager.close();
+ }
+
+ public void put(K key, V value) {
+ primaryCache.put(key, value);
+ }
+
+ public V get(K key) {
+ return primaryCache.get(key);
+ }
+
+ public V getSecondary(K key) {
+ return secondaryCache.get(key);
+ }
+
+ public void remove(K key) {
+ primaryCache.remove(key);
+ }
+}
diff --git a/jcache/configure-cache-listener/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java b/jcache/configure-cache-listener/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java
new file mode 100644
index 00000000..babad1ca
--- /dev/null
+++ b/jcache/configure-cache-listener/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java
@@ -0,0 +1,49 @@
+package org.javaee8.jcache.configuration;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class, KeyValueEntryRemovedListener.class)
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+
+ @Test
+ public void test() throws Exception {
+ // empty both primary ans secondary caches
+ assertNull(service.get("JSR107"));
+ assertNull(service.getSecondary("JSR107"));
+
+ // available only in primary cache
+ service.put("JSR107", "JCACHE");
+ assertEquals("JCACHE", service.get("JSR107"));
+ assertNull(service.getSecondary("JSR107"));
+
+ // removed from primary cache, but available in secondary cache
+ service.remove("JSR107");
+ assertNull(service.get("JSR107"));
+ assertEquals("JCACHE", service.getSecondary("JSR107"));
+ }
+}
diff --git a/jcache/configure-cache-listener/src/test/resources/beans.xml b/jcache/configure-cache-listener/src/test/resources/beans.xml
new file mode 100644
index 00000000..ae366cab
--- /dev/null
+++ b/jcache/configure-cache-listener/src/test/resources/beans.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/jcache/configure-cache-listener/src/test/resources/jboss-deployment-structure.xml b/jcache/configure-cache-listener/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/configure-cache-listener/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/configure-cache-loaders/pom.xml b/jcache/configure-cache-loaders/pom.xml
new file mode 100644
index 00000000..5fb64932
--- /dev/null
+++ b/jcache/configure-cache-loaders/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ configure-cache-loaders
+
diff --git a/jcache/configure-cache-loaders/src/main/java/org/javaee8/jcache/configuration/KeyValueLoaderWriter.java b/jcache/configure-cache-loaders/src/main/java/org/javaee8/jcache/configuration/KeyValueLoaderWriter.java
new file mode 100644
index 00000000..c5e4e079
--- /dev/null
+++ b/jcache/configure-cache-loaders/src/main/java/org/javaee8/jcache/configuration/KeyValueLoaderWriter.java
@@ -0,0 +1,66 @@
+package org.javaee8.jcache.configuration;
+
+import javax.cache.Cache;
+import javax.cache.integration.CacheLoader;
+import javax.cache.integration.CacheLoaderException;
+import javax.cache.integration.CacheWriter;
+import javax.cache.integration.CacheWriterException;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class KeyValueLoaderWriter implements CacheLoader, CacheWriter, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private Map storage = new HashMap<>();
+
+ KeyValueLoaderWriter() {
+ storage.put("JSR107", "JCACHE");
+ storage.put("JSR365", "CDI 2.0");
+ storage.put("JSR367", "JSON-B");
+ }
+
+ @Override
+ public String load(String key) throws CacheLoaderException {
+ return storage.get(key);
+ }
+
+ @Override
+ public Map loadAll(Iterable extends String> keys) throws CacheLoaderException {
+ final Map result = new HashMap<>();
+ keys.forEach((key) -> {
+ String value = load(key);
+ if (value != null) {
+ result.put(key, value);
+ }
+ });
+ return result;
+ }
+
+ @Override
+ public void write(Cache.Entry extends String, ? extends String> entry) throws CacheWriterException {
+ storage.put(entry.getKey(), entry.getValue());
+ }
+
+ @Override
+ public void writeAll(Collection> entries) throws CacheWriterException {
+ entries.forEach(this::write);
+ }
+
+ @Override
+ public void delete(Object key) throws CacheWriterException {
+ if (key instanceof String) {
+ storage.remove(key);
+ }
+ }
+
+ @Override
+ public void deleteAll(Collection> keys) throws CacheWriterException {
+ keys.forEach(this::delete);
+ }
+}
diff --git a/jcache/configure-cache-loaders/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java b/jcache/configure-cache-loaders/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java
new file mode 100644
index 00000000..bcd34f2b
--- /dev/null
+++ b/jcache/configure-cache-loaders/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java
@@ -0,0 +1,69 @@
+package org.javaee8.jcache.configuration;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.configuration.Factory;
+import javax.cache.configuration.FactoryBuilder;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.spi.CachingProvider;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class KeyValueService {
+ private CacheManager cacheManager;
+ private Cache cache;
+
+ @PostConstruct
+ void init() {
+ CachingProvider cachingProvider = Caching.getCachingProvider();
+ cacheManager = cachingProvider.getCacheManager();
+
+ MutableConfiguration config = new MutableConfiguration<>();
+
+ // synchronization with an external resource when cache entries are read
+ Factory factory = FactoryBuilder.factoryOf(new KeyValueLoaderWriter());
+ config.setCacheLoaderFactory(factory).setReadThrough(true);
+
+ // synchronization with an external resource when cache entries are updated and deleted
+ config.setCacheWriterFactory(factory).setWriteThrough(true);
+
+ cache = cacheManager.createCache("cache.default", config);
+ }
+
+ @PreDestroy
+ void destroy() {
+ cacheManager.close();
+ }
+
+ public void put(String key, String value) {
+ cache.put(key, value);
+ }
+
+ public void putAll(Map map) {
+ cache.putAll(map);
+ }
+
+ public String get(String key) {
+ return cache.get(key);
+ }
+
+ public Map getAll(String... keys) {
+ return cache.getAll(Arrays.stream(keys).collect(Collectors.toSet()));
+ }
+
+ public void remove(String key) {
+ cache.remove(key);
+ }
+
+ public void removeAll(String... keys) {
+ cache.removeAll(Arrays.stream(keys).collect(Collectors.toSet()));
+ }
+}
diff --git a/jcache/configure-cache-loaders/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java b/jcache/configure-cache-loaders/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java
new file mode 100644
index 00000000..b22c2f5d
--- /dev/null
+++ b/jcache/configure-cache-loaders/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java
@@ -0,0 +1,64 @@
+package org.javaee8.jcache.configuration;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class, KeyValueLoaderWriter.class)
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+
+ @Test
+ public void test() throws Exception {
+ // should be available because of cache loader
+ assertEquals("JCACHE", service.get("JSR107"));
+ assertEquals("CDI 2.0", service.get("JSR365"));
+ assertEquals("JSON-B", service.get("JSR367"));
+
+ // remove single entry
+ service.remove("JSR367");
+ assertNull(service.get("JSR367"));
+
+ // add single entry
+ assertNull(service.get("JSR371"));
+ service.put("JSR371", "MVC 1.0");
+ assertEquals("MVC 1.0", service.get("JSR371"));
+
+ // remove multiple entries
+ service.removeAll("JSR107", "JSR365");
+ assertNull(service.get("JSR107"));
+ assertNull(service.get("JSR365"));
+
+ // add multiple entries
+ Map newSpecs = new HashMap<>();
+ newSpecs.put("JSR370", "JAX-RS 2.1");
+ newSpecs.put("JSR372", "JSF 2.3");
+ service.putAll(newSpecs);
+ assertEquals("JAX-RS 2.1", service.get("JSR370"));
+ assertEquals("JSF 2.3", service.get("JSR372"));
+ }
+}
diff --git a/jcache/configure-cache-loaders/src/test/resources/beans.xml b/jcache/configure-cache-loaders/src/test/resources/beans.xml
new file mode 100644
index 00000000..ae366cab
--- /dev/null
+++ b/jcache/configure-cache-loaders/src/test/resources/beans.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/jcache/configure-cache-loaders/src/test/resources/jboss-deployment-structure.xml b/jcache/configure-cache-loaders/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/configure-cache-loaders/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/configure-cache-store-by/pom.xml b/jcache/configure-cache-store-by/pom.xml
new file mode 100644
index 00000000..154a3fec
--- /dev/null
+++ b/jcache/configure-cache-store-by/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ configure-cache-store-by
+
diff --git a/jcache/configure-cache-store-by/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java b/jcache/configure-cache-store-by/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java
new file mode 100644
index 00000000..87ed33b2
--- /dev/null
+++ b/jcache/configure-cache-store-by/src/main/java/org/javaee8/jcache/configuration/KeyValueService.java
@@ -0,0 +1,49 @@
+package org.javaee8.jcache.configuration;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.spi.CachingProvider;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class KeyValueService {
+ public static final String CACHE_BY_VALUE = "cache.by.value";
+ public static final String CACHE_BY_REFERENCE = "cache.by.reference";
+
+ private CacheManager cacheManager;
+
+ @PostConstruct
+ void init() {
+ CachingProvider cachingProvider = Caching.getCachingProvider();
+ cacheManager = cachingProvider.getCacheManager();
+
+ MutableConfiguration config = new MutableConfiguration<>();
+ // by default store by value both cache keys and values
+ cacheManager.createCache(CACHE_BY_VALUE, config);
+
+ // store both keys and values by reference so that their subsequent changes are reflected in cache
+ config.setStoreByValue(false);
+ cacheManager.createCache(CACHE_BY_REFERENCE, config);
+ }
+
+ @PreDestroy
+ void destroy() {
+ cacheManager.close();
+ }
+
+ public void put(String cacheName, K key, V value) {
+ Cache cache = cacheManager.getCache(cacheName);
+ cache.put(key, value);
+ }
+
+ public V get(String cacheName, K key) {
+ Cache cache = cacheManager.getCache(cacheName);
+ return cache.get(key);
+ }
+}
diff --git a/jcache/configure-cache-store-by/src/main/java/org/javaee8/jcache/configuration/MyKey.java b/jcache/configure-cache-store-by/src/main/java/org/javaee8/jcache/configuration/MyKey.java
new file mode 100644
index 00000000..05bd59b0
--- /dev/null
+++ b/jcache/configure-cache-store-by/src/main/java/org/javaee8/jcache/configuration/MyKey.java
@@ -0,0 +1,42 @@
+package org.javaee8.jcache.configuration;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class MyKey implements Serializable {
+ private String key;
+
+ public MyKey(String key) {
+ this.key = key;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MyKey that = (MyKey) o;
+ return Objects.equals(key, that.key);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(key);
+ }
+
+ @Override
+ public String toString() {
+ return getKey();
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+}
diff --git a/jcache/configure-cache-store-by/src/main/java/org/javaee8/jcache/configuration/MyValue.java b/jcache/configure-cache-store-by/src/main/java/org/javaee8/jcache/configuration/MyValue.java
new file mode 100644
index 00000000..b9d77aa2
--- /dev/null
+++ b/jcache/configure-cache-store-by/src/main/java/org/javaee8/jcache/configuration/MyValue.java
@@ -0,0 +1,37 @@
+package org.javaee8.jcache.configuration;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class MyValue implements Serializable {
+ private String value;
+
+ public MyValue(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MyValue that = (MyValue) o;
+ return Objects.equals(value, that.value);
+ }
+
+ @Override
+ public String toString() {
+ return getValue();
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/jcache/configure-cache-store-by/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java b/jcache/configure-cache-store-by/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java
new file mode 100644
index 00000000..b66b10c9
--- /dev/null
+++ b/jcache/configure-cache-store-by/src/test/java/org/javaee8/jcache/configuration/KeyValueServiceTest.java
@@ -0,0 +1,67 @@
+package org.javaee8.jcache.configuration;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class, MyKey.class, MyValue.class)
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+
+ private MyKey myKey = new MyKey("JSR107");
+ private MyValue myValue = new MyValue("JCACHE");
+
+ // todo: store by value produces CNFE
+/*
+ @Test
+ public void testImmutable() throws Exception {
+ // use cache where keys and values are maintained by value
+ String cacheName = KeyValueService.CACHE_BY_VALUE;
+
+ service.put(cacheName, myKey, this.myValue);
+ MyValue myValue = service.get(cacheName, myKey);
+
+ // different references
+ assertNotSame(this.myValue, myValue);
+ // but the same values
+ assertEquals(this.myValue, myValue);
+
+ // change value returned from cache
+ myValue.setValue("JSON-B");
+ assertNotEquals(myValue, service.get(cacheName, myKey));
+ }
+*/
+
+ @Test
+ public void testMutable() throws Exception {
+ // use cache where keys and values are maintained by reference
+ String cacheName = KeyValueService.CACHE_BY_REFERENCE;
+
+ service.put(cacheName, myKey, this.myValue);
+ MyValue myValue = service.get(cacheName, myKey);
+
+ // the same references (and thus the same values)
+ assertSame(this.myValue, myValue);
+ }
+}
diff --git a/jcache/configure-cache-store-by/src/test/resources/beans.xml b/jcache/configure-cache-store-by/src/test/resources/beans.xml
new file mode 100644
index 00000000..ae366cab
--- /dev/null
+++ b/jcache/configure-cache-store-by/src/test/resources/beans.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/jcache/configure-cache-store-by/src/test/resources/jboss-deployment-structure.xml b/jcache/configure-cache-store-by/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/configure-cache-store-by/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-eviction/pom.xml b/jcache/infinispan-eviction/pom.xml
new file mode 100644
index 00000000..70783b78
--- /dev/null
+++ b/jcache/infinispan-eviction/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ infinispan-eviction
+
diff --git a/jcache/infinispan-eviction/src/main/java/org/javaee8/jcache/infinispan/eviction/KeyValueService.java b/jcache/infinispan-eviction/src/main/java/org/javaee8/jcache/infinispan/eviction/KeyValueService.java
new file mode 100644
index 00000000..9910f3e7
--- /dev/null
+++ b/jcache/infinispan-eviction/src/main/java/org/javaee8/jcache/infinispan/eviction/KeyValueService.java
@@ -0,0 +1,52 @@
+package org.javaee8.jcache.infinispan.eviction;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.spi.CachingProvider;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class KeyValueService {
+ public static final String CACHE_NAME = "defaultCache";
+
+ private CacheManager cacheManager;
+
+ @PostConstruct
+ void init() {
+ CachingProvider cachingProvider = Caching.getCachingProvider();
+ URI configUri = URI.create("META-INF/infinispan.xml");
+ cacheManager = cachingProvider.getCacheManager(configUri, cachingProvider.getDefaultClassLoader());
+ }
+
+ @PreDestroy
+ void destroy() {
+ cacheManager.close();
+ }
+
+ public void put(K key, V value) {
+ Cache cache = cacheManager.getCache(CACHE_NAME);
+ cache.put(key, value);
+ }
+
+ public V get(K key) {
+ Cache cache = cacheManager.getCache(CACHE_NAME);
+ return cache.get(key);
+ }
+
+ public Set getKeys() {
+ Cache cache = cacheManager.getCache(CACHE_NAME);
+ Set keys = new HashSet<>();
+ for (Cache.Entry entry : cache) {
+ keys.add(entry.getKey());
+ }
+ return keys;
+ }
+}
diff --git a/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/BinaryStorageTest.java b/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/BinaryStorageTest.java
new file mode 100644
index 00000000..fa7c962b
--- /dev/null
+++ b/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/BinaryStorageTest.java
@@ -0,0 +1,25 @@
+package org.javaee8.jcache.infinispan.eviction;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.runner.RunWith;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class BinaryStorageTest extends KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class, KeyValueServiceTest.class)
+ .addAsResource("infinispan-binary.xml", "META-INF/infinispan.xml")
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+}
diff --git a/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/KeyValueServiceTest.java b/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/KeyValueServiceTest.java
new file mode 100644
index 00000000..c064172c
--- /dev/null
+++ b/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/KeyValueServiceTest.java
@@ -0,0 +1,40 @@
+package org.javaee8.jcache.infinispan.eviction;
+
+import org.junit.Test;
+
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+
+/**
+ * @author Radim Hanus
+ */
+abstract class KeyValueServiceTest {
+ @Inject
+ private KeyValueService service;
+
+ @Test
+ public void test() throws Exception {
+ assertNull(service.get("JSR107"));
+ service.put("JSR107", "JCACHE");
+ assertEquals("JCACHE", service.get("JSR107"));
+ assertEquals(1, service.getKeys().size());
+
+ assertNull(service.get("JSR365"));
+ service.put("JSR365", "CDI 2.0");
+ assertEquals("CDI 2.0", service.get("JSR365"));
+ assertEquals(2, service.getKeys().size());
+
+ assertNull(service.get("JSR367"));
+ service.put("JSR367", "JSON-B");
+ assertEquals("JSON-B", service.get("JSR367"));
+ assertEquals(2, service.getKeys().size());
+
+ assertNull(service.get("JSR371"));
+ service.put("JSR371", "MVC 1.0");
+ assertEquals("MVC 1.0", service.get("JSR371"));
+ assertEquals(2, service.getKeys().size());
+ }
+}
diff --git a/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/ObjectStorageTest.java b/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/ObjectStorageTest.java
new file mode 100644
index 00000000..ccf85e95
--- /dev/null
+++ b/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/ObjectStorageTest.java
@@ -0,0 +1,25 @@
+package org.javaee8.jcache.infinispan.eviction;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.runner.RunWith;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class ObjectStorageTest extends KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class, KeyValueServiceTest.class)
+ .addAsResource("infinispan-object.xml", "META-INF/infinispan.xml")
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+}
diff --git a/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/OffHeapStorageTest.java b/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/OffHeapStorageTest.java
new file mode 100644
index 00000000..9ec4c1f0
--- /dev/null
+++ b/jcache/infinispan-eviction/src/test/java/org/javaee8/jcache/infinispan/eviction/OffHeapStorageTest.java
@@ -0,0 +1,25 @@
+package org.javaee8.jcache.infinispan.eviction;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.runner.RunWith;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class OffHeapStorageTest extends KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class, KeyValueServiceTest.class)
+ .addAsResource("infinispan-off-heap.xml", "META-INF/infinispan.xml")
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+}
diff --git a/jcache/infinispan-eviction/src/test/resources/beans.xml b/jcache/infinispan-eviction/src/test/resources/beans.xml
new file mode 100644
index 00000000..ae366cab
--- /dev/null
+++ b/jcache/infinispan-eviction/src/test/resources/beans.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/jcache/infinispan-eviction/src/test/resources/infinispan-binary.xml b/jcache/infinispan-eviction/src/test/resources/infinispan-binary.xml
new file mode 100644
index 00000000..3bce22d4
--- /dev/null
+++ b/jcache/infinispan-eviction/src/test/resources/infinispan-binary.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-eviction/src/test/resources/infinispan-object.xml b/jcache/infinispan-eviction/src/test/resources/infinispan-object.xml
new file mode 100644
index 00000000..b03e61bb
--- /dev/null
+++ b/jcache/infinispan-eviction/src/test/resources/infinispan-object.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-eviction/src/test/resources/infinispan-off-heap.xml b/jcache/infinispan-eviction/src/test/resources/infinispan-off-heap.xml
new file mode 100644
index 00000000..0517b4e5
--- /dev/null
+++ b/jcache/infinispan-eviction/src/test/resources/infinispan-off-heap.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-eviction/src/test/resources/jboss-deployment-structure.xml b/jcache/infinispan-eviction/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/infinispan-eviction/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-externalizer/pom.xml b/jcache/infinispan-externalizer/pom.xml
new file mode 100644
index 00000000..964d18be
--- /dev/null
+++ b/jcache/infinispan-externalizer/pom.xml
@@ -0,0 +1,21 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ infinispan-externalizer
+
+
+
+ org.infinispan
+ infinispan-commons
+ provided
+
+
+
+
diff --git a/jcache/infinispan-externalizer/src/main/java/org/javaee8/jcache/infinispan/externalize/KeyValueService.java b/jcache/infinispan-externalizer/src/main/java/org/javaee8/jcache/infinispan/externalize/KeyValueService.java
new file mode 100644
index 00000000..16d799e7
--- /dev/null
+++ b/jcache/infinispan-externalizer/src/main/java/org/javaee8/jcache/infinispan/externalize/KeyValueService.java
@@ -0,0 +1,41 @@
+package org.javaee8.jcache.infinispan.externalize;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.spi.CachingProvider;
+import java.net.URI;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class KeyValueService {
+ public static final String CACHE_NAME = "defaultCache";
+
+ private CacheManager cacheManager;
+
+ @PostConstruct
+ void init() {
+ CachingProvider cachingProvider = Caching.getCachingProvider();
+ URI configUri = URI.create("META-INF/infinispan.xml");
+ cacheManager = cachingProvider.getCacheManager(configUri, cachingProvider.getDefaultClassLoader());
+ }
+
+ @PreDestroy
+ void destroy() {
+ cacheManager.close();
+ }
+
+ public void put(K key, V value) {
+ Cache cache = cacheManager.getCache(CACHE_NAME);
+ cache.put(key, value);
+ }
+
+ public V get(K key) {
+ Cache cache = cacheManager.getCache(CACHE_NAME);
+ return cache.get(key);
+ }
+}
diff --git a/jcache/infinispan-externalizer/src/main/java/org/javaee8/jcache/infinispan/externalize/MyValue.java b/jcache/infinispan-externalizer/src/main/java/org/javaee8/jcache/infinispan/externalize/MyValue.java
new file mode 100644
index 00000000..f8e0f37b
--- /dev/null
+++ b/jcache/infinispan-externalizer/src/main/java/org/javaee8/jcache/infinispan/externalize/MyValue.java
@@ -0,0 +1,37 @@
+package org.javaee8.jcache.infinispan.externalize;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class MyValue implements Serializable {
+ private String value;
+
+ public MyValue(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MyValue that = (MyValue) o;
+ return Objects.equals(value, that.value);
+ }
+
+ @Override
+ public String toString() {
+ return getValue();
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/jcache/infinispan-externalizer/src/main/java/org/javaee8/jcache/infinispan/externalize/MyValueExternalizer.java b/jcache/infinispan-externalizer/src/main/java/org/javaee8/jcache/infinispan/externalize/MyValueExternalizer.java
new file mode 100644
index 00000000..2a37bb1f
--- /dev/null
+++ b/jcache/infinispan-externalizer/src/main/java/org/javaee8/jcache/infinispan/externalize/MyValueExternalizer.java
@@ -0,0 +1,35 @@
+package org.javaee8.jcache.infinispan.externalize;
+
+import org.infinispan.commons.marshall.AdvancedExternalizer;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.Set;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class MyValueExternalizer implements AdvancedExternalizer {
+ @Override
+ public Set> getTypeClasses() {
+ return Collections.singleton(MyValue.class);
+ }
+
+ @Override
+ public Integer getId() {
+ return 123;
+ }
+
+ @Override
+ public void writeObject(ObjectOutput objectOutput, MyValue myValue) throws IOException {
+ objectOutput.writeObject(myValue.getValue());
+ }
+
+ @Override
+ public MyValue readObject(ObjectInput objectInput) throws IOException, ClassNotFoundException {
+ return new MyValue((String) objectInput.readObject());
+ }
+}
diff --git a/jcache/infinispan-externalizer/src/test/java/org/javaee8/jcache/infinispan/externalize/KeyValueServiceTest.java b/jcache/infinispan-externalizer/src/test/java/org/javaee8/jcache/infinispan/externalize/KeyValueServiceTest.java
new file mode 100644
index 00000000..511bf4d4
--- /dev/null
+++ b/jcache/infinispan-externalizer/src/test/java/org/javaee8/jcache/infinispan/externalize/KeyValueServiceTest.java
@@ -0,0 +1,53 @@
+package org.javaee8.jcache.infinispan.externalize;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+
+import static junit.framework.TestCase.assertNotSame;
+import static org.junit.Assert.*;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class, MyValue.class, MyValueExternalizer.class)
+ .addAsResource("infinispan.xml", "META-INF/infinispan.xml")
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+
+ private String myKey = "JSR107";
+ private MyValue myValue = new MyValue("JCACHE");
+
+ @Test
+ public void test() throws Exception {
+ assertNull(service.get(myKey));
+ service.put(myKey, this.myValue);
+
+ MyValue myValue = service.get(myKey);
+
+ // different references
+ assertNotSame(this.myValue, myValue);
+ // but the same values
+ assertEquals(this.myValue, myValue);
+
+ // change value returned from cache
+ myValue.setValue("JSON-B");
+ assertNotEquals(myValue, service.get(myKey));
+ }
+}
diff --git a/jcache/infinispan-externalizer/src/test/resources/beans.xml b/jcache/infinispan-externalizer/src/test/resources/beans.xml
new file mode 100644
index 00000000..ae366cab
--- /dev/null
+++ b/jcache/infinispan-externalizer/src/test/resources/beans.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/jcache/infinispan-externalizer/src/test/resources/infinispan.xml b/jcache/infinispan-externalizer/src/test/resources/infinispan.xml
new file mode 100644
index 00000000..b3fe2b55
--- /dev/null
+++ b/jcache/infinispan-externalizer/src/test/resources/infinispan.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-externalizer/src/test/resources/jboss-deployment-structure.xml b/jcache/infinispan-externalizer/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/infinispan-externalizer/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-transaction-isolation/pom.xml b/jcache/infinispan-transaction-isolation/pom.xml
new file mode 100644
index 00000000..d470b846
--- /dev/null
+++ b/jcache/infinispan-transaction-isolation/pom.xml
@@ -0,0 +1,21 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ infinispan-transaction-isolation
+
+
+
+ org.infinispan
+ infinispan-commons
+ provided
+
+
+
+
diff --git a/jcache/infinispan-transaction-isolation/src/main/java/org/javaee8/jcache/infinispan/transaction/isolation/KeyValueService.java b/jcache/infinispan-transaction-isolation/src/main/java/org/javaee8/jcache/infinispan/transaction/isolation/KeyValueService.java
new file mode 100644
index 00000000..8bf76615
--- /dev/null
+++ b/jcache/infinispan-transaction-isolation/src/main/java/org/javaee8/jcache/infinispan/transaction/isolation/KeyValueService.java
@@ -0,0 +1,45 @@
+package org.javaee8.jcache.infinispan.transaction.isolation;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.spi.CachingProvider;
+import javax.enterprise.context.ApplicationScoped;
+import javax.transaction.Transactional;
+import java.net.URI;
+
+
+/**
+ * @author Radim Hanus
+ */
+@ApplicationScoped
+@Transactional
+public class KeyValueService {
+ private static final String CACHE_NAME = "defaultCache";
+
+ private CacheManager cacheManager;
+ private Cache cache;
+
+ @PostConstruct
+ void init() {
+ CachingProvider cachingProvider = Caching.getCachingProvider();
+ URI configUri = URI.create("META-INF/infinispan.xml");
+ cacheManager = cachingProvider.getCacheManager(configUri, cachingProvider.getDefaultClassLoader());
+ cache = cacheManager.getCache(CACHE_NAME);
+ }
+
+ @PreDestroy
+ void destroy() {
+ cacheManager.close();
+ }
+
+ public void put(String key, String value) {
+ cache.put(key, value);
+ }
+
+ public String get(String key) {
+ return cache.get(key);
+ }
+}
diff --git a/jcache/infinispan-transaction-isolation/src/test/java/org/javaee8/jcache/infinispan/transaction/isolation/ReadCommittedIsolationTest.java b/jcache/infinispan-transaction-isolation/src/test/java/org/javaee8/jcache/infinispan/transaction/isolation/ReadCommittedIsolationTest.java
new file mode 100644
index 00000000..c2b6eb00
--- /dev/null
+++ b/jcache/infinispan-transaction-isolation/src/test/java/org/javaee8/jcache/infinispan/transaction/isolation/ReadCommittedIsolationTest.java
@@ -0,0 +1,91 @@
+package org.javaee8.jcache.infinispan.transaction.isolation;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.annotation.Resource;
+import javax.enterprise.concurrent.ManagedExecutorService;
+import javax.inject.Inject;
+import javax.naming.InitialContext;
+import javax.transaction.UserTransaction;
+import java.util.concurrent.CyclicBarrier;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class ReadCommittedIsolationTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class)
+ .addAsResource("infinispan-isolation-read_commited.xml", "META-INF/infinispan.xml")
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Resource
+ private ManagedExecutorService executorService;
+
+ @Inject
+ private KeyValueService service;
+
+ @Test
+ public void test() throws Exception {
+ // put an entry
+ service.put("JSR107", "JCACHE");
+
+ final CyclicBarrier barrier = new CyclicBarrier(2);
+
+ executorService.execute(() -> {
+ try {
+ UserTransaction transaction = InitialContext.doLookup("java:comp/UserTransaction");
+ transaction.begin();
+
+ // ensure both threads started a tx and see expected value
+ assertEquals("JCACHE", service.get("JSR107"));
+ barrier.await();
+
+ // update the entry value
+ service.put("JSR107", "CDI 2.0");
+
+ transaction.commit();
+
+ // signal the change
+ barrier.await();
+ } catch (Throwable e) {
+ fail(e.getMessage());
+ }
+ });
+
+ executorService.execute(() -> {
+ try {
+ UserTransaction transaction = InitialContext.doLookup("java:comp/UserTransaction");
+ transaction.begin();
+
+ // ensure both threads started a tx and see expected value
+ assertEquals("JCACHE", service.get("JSR107"));
+ barrier.await();
+
+ // entry value has been changed
+ barrier.await();
+
+ // should see the change in existing tx
+ assertEquals("CDI 2.0", service.get("JSR107"));
+
+ transaction.commit();
+ } catch (Throwable e) {
+ fail(e.getMessage());
+ }
+ });
+ }
+}
diff --git a/jcache/infinispan-transaction-isolation/src/test/java/org/javaee8/jcache/infinispan/transaction/isolation/RepeatableReadIsolationTest.java b/jcache/infinispan-transaction-isolation/src/test/java/org/javaee8/jcache/infinispan/transaction/isolation/RepeatableReadIsolationTest.java
new file mode 100644
index 00000000..92801380
--- /dev/null
+++ b/jcache/infinispan-transaction-isolation/src/test/java/org/javaee8/jcache/infinispan/transaction/isolation/RepeatableReadIsolationTest.java
@@ -0,0 +1,94 @@
+package org.javaee8.jcache.infinispan.transaction.isolation;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.annotation.Resource;
+import javax.enterprise.concurrent.ManagedExecutorService;
+import javax.inject.Inject;
+import javax.naming.InitialContext;
+import javax.transaction.UserTransaction;
+import java.util.concurrent.CyclicBarrier;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class RepeatableReadIsolationTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class)
+ .addAsResource("infinispan-isolation-repeatable_read.xml", "META-INF/infinispan.xml")
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Resource
+ private ManagedExecutorService executorService;
+
+ @Inject
+ private KeyValueService service;
+
+ @Test
+ public void test() throws Exception {
+ // put an entry
+ service.put("JSR107", "JCACHE");
+
+ final CyclicBarrier barrier = new CyclicBarrier(2);
+
+ executorService.submit(() -> {
+ try {
+ UserTransaction transaction = InitialContext.doLookup("java:comp/UserTransaction");
+ transaction.begin();
+
+ // ensure both threads started a tx and see expected value
+ assertEquals("JCACHE", service.get("JSR107"));
+ barrier.await();
+
+ // update the entry value
+ service.put("JSR107", "CDI 2.0");
+
+ transaction.commit();
+
+ // signal the change
+ barrier.await();
+ } catch (Throwable e) {
+ fail(e.getMessage());
+ }
+ });
+
+ executorService.submit(() -> {
+ try {
+ UserTransaction transaction = InitialContext.doLookup("java:comp/UserTransaction");
+ transaction.begin();
+
+ // ensure both threads started a tx and see expected value
+ assertEquals("JCACHE", service.get("JSR107"));
+ barrier.await();
+
+ // entry value has been changed
+ barrier.await();
+
+ // shouldn't see the change in existing tx
+ assertEquals("JCACHE", service.get("JSR107"));
+
+ transaction.commit();
+
+ // should see the change in new tx
+ assertEquals("CDI 2.0", service.get("JSR107"));
+ } catch (Throwable e) {
+ fail(e.getMessage());
+ }
+ });
+ }
+}
diff --git a/jcache/infinispan-transaction-isolation/src/test/resources/beans.xml b/jcache/infinispan-transaction-isolation/src/test/resources/beans.xml
new file mode 100644
index 00000000..4bb6b47b
--- /dev/null
+++ b/jcache/infinispan-transaction-isolation/src/test/resources/beans.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/jcache/infinispan-transaction-isolation/src/test/resources/infinispan-isolation-read_commited.xml b/jcache/infinispan-transaction-isolation/src/test/resources/infinispan-isolation-read_commited.xml
new file mode 100644
index 00000000..c4e20daa
--- /dev/null
+++ b/jcache/infinispan-transaction-isolation/src/test/resources/infinispan-isolation-read_commited.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-transaction-isolation/src/test/resources/infinispan-isolation-repeatable_read.xml b/jcache/infinispan-transaction-isolation/src/test/resources/infinispan-isolation-repeatable_read.xml
new file mode 100644
index 00000000..beed0372
--- /dev/null
+++ b/jcache/infinispan-transaction-isolation/src/test/resources/infinispan-isolation-repeatable_read.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-transaction-isolation/src/test/resources/jboss-deployment-structure.xml b/jcache/infinispan-transaction-isolation/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/infinispan-transaction-isolation/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-transaction-mode/pom.xml b/jcache/infinispan-transaction-mode/pom.xml
new file mode 100644
index 00000000..2e2392d2
--- /dev/null
+++ b/jcache/infinispan-transaction-mode/pom.xml
@@ -0,0 +1,21 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ infinispan-transaction-mode
+
+
+
+ org.infinispan
+ infinispan-commons
+ provided
+
+
+
+
diff --git a/jcache/infinispan-transaction-mode/src/main/java/org/javaee8/jcache/infinispan/transaction/mode/KeyValueService.java b/jcache/infinispan-transaction-mode/src/main/java/org/javaee8/jcache/infinispan/transaction/mode/KeyValueService.java
new file mode 100644
index 00000000..43270cca
--- /dev/null
+++ b/jcache/infinispan-transaction-mode/src/main/java/org/javaee8/jcache/infinispan/transaction/mode/KeyValueService.java
@@ -0,0 +1,43 @@
+package org.javaee8.jcache.infinispan.transaction.mode;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.spi.CachingProvider;
+import javax.transaction.Transactional;
+import java.net.URI;
+
+
+/**
+ * @author Radim Hanus
+ */
+@Transactional
+public class KeyValueService {
+ public static final String CACHE_NAME = "defaultCache";
+
+ private CacheManager cacheManager;
+
+ @PostConstruct
+ void init() {
+ CachingProvider cachingProvider = Caching.getCachingProvider();
+ URI configUri = URI.create("META-INF/infinispan.xml");
+ cacheManager = cachingProvider.getCacheManager(configUri, cachingProvider.getDefaultClassLoader());
+ }
+
+ @PreDestroy
+ void destroy() {
+ cacheManager.close();
+ }
+
+ public void put(K key, V value) {
+ Cache cache = cacheManager.getCache(CACHE_NAME);
+ cache.put(key, value);
+ }
+
+ public V get(K key) {
+ Cache cache = cacheManager.getCache(CACHE_NAME);
+ return cache.get(key);
+ }
+}
diff --git a/jcache/infinispan-transaction-mode/src/test/java/org/javaee8/jcache/infinispan/transaction/mode/NonXaTransactionTest.java b/jcache/infinispan-transaction-mode/src/test/java/org/javaee8/jcache/infinispan/transaction/mode/NonXaTransactionTest.java
new file mode 100644
index 00000000..879cc881
--- /dev/null
+++ b/jcache/infinispan-transaction-mode/src/test/java/org/javaee8/jcache/infinispan/transaction/mode/NonXaTransactionTest.java
@@ -0,0 +1,57 @@
+package org.javaee8.jcache.infinispan.transaction.mode;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+import javax.transaction.UserTransaction;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class NonXaTransactionTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class)
+ .addAsResource("infinispan-txmode-non_xa.xml", "META-INF/infinispan.xml")
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+ @Inject
+ private UserTransaction transaction;
+
+ @Test
+ public void test() throws Exception {
+ transaction.begin();
+ service.put("JSR107", "JCACHE");
+ service.put("JSR365", "CDI 2.0");
+ transaction.commit();
+
+ // after commit entries should be available
+ assertEquals("JCACHE", service.get("JSR107"));
+ assertEquals("CDI 2.0", service.get("JSR365"));
+
+ transaction.begin();
+ service.put("JSR367", "JSON-B");
+ service.put("JSR371", "MVC 1.0");
+ transaction.rollback();
+
+ // after rollback entries shouldn't be available
+ assertNull(service.get("JSR367"));
+ assertNull(service.get("JSR371"));
+ }
+}
diff --git a/jcache/infinispan-transaction-mode/src/test/java/org/javaee8/jcache/infinispan/transaction/mode/NoneTransactionTest.java b/jcache/infinispan-transaction-mode/src/test/java/org/javaee8/jcache/infinispan/transaction/mode/NoneTransactionTest.java
new file mode 100644
index 00000000..6bc03506
--- /dev/null
+++ b/jcache/infinispan-transaction-mode/src/test/java/org/javaee8/jcache/infinispan/transaction/mode/NoneTransactionTest.java
@@ -0,0 +1,56 @@
+package org.javaee8.jcache.infinispan.transaction.mode;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+import javax.transaction.UserTransaction;
+
+import static org.junit.Assert.assertEquals;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class NoneTransactionTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class)
+ .addAsResource("infinispan-txmode-none.xml", "META-INF/infinispan.xml")
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+ @Inject
+ private UserTransaction transaction;
+
+ @Test
+ public void test() throws Exception {
+ transaction.begin();
+ service.put("JSR107", "JCACHE");
+ service.put("JSR365", "CDI 2.0");
+ transaction.commit();
+
+ // no matter of transaction result entries should be available
+ assertEquals("JCACHE", service.get("JSR107"));
+ assertEquals("CDI 2.0", service.get("JSR365"));
+
+ transaction.begin();
+ service.put("JSR367", "JSON-B");
+ service.put("JSR371", "MVC 1.0");
+ transaction.rollback();
+
+ // no matter of transaction result entries should be available
+ assertEquals("JSON-B", service.get("JSR367"));
+ assertEquals("MVC 1.0", service.get("JSR371"));
+ }
+}
diff --git a/jcache/infinispan-transaction-mode/src/test/resources/beans.xml b/jcache/infinispan-transaction-mode/src/test/resources/beans.xml
new file mode 100644
index 00000000..ae366cab
--- /dev/null
+++ b/jcache/infinispan-transaction-mode/src/test/resources/beans.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/jcache/infinispan-transaction-mode/src/test/resources/infinispan-txmode-non_xa.xml b/jcache/infinispan-transaction-mode/src/test/resources/infinispan-txmode-non_xa.xml
new file mode 100644
index 00000000..c86cfe88
--- /dev/null
+++ b/jcache/infinispan-transaction-mode/src/test/resources/infinispan-txmode-non_xa.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-transaction-mode/src/test/resources/infinispan-txmode-none.xml b/jcache/infinispan-transaction-mode/src/test/resources/infinispan-txmode-none.xml
new file mode 100644
index 00000000..b120a9d3
--- /dev/null
+++ b/jcache/infinispan-transaction-mode/src/test/resources/infinispan-txmode-none.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/infinispan-transaction-mode/src/test/resources/jboss-deployment-structure.xml b/jcache/infinispan-transaction-mode/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/infinispan-transaction-mode/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jcache/pom.xml b/jcache/pom.xml
new file mode 100644
index 00000000..ebc8c016
--- /dev/null
+++ b/jcache/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+
+
+ org.javaee8
+ javaee8-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ pom
+ JSR 107: JCACHE Samples
+
+
+
+ 8.2.4.Final
+
+
+
+ annotation-cache-result
+ annotation-cache-put
+ annotation-cache-remove
+ annotation-cache-remove-all
+ configure-cache-expiry
+ configure-cache-loaders
+ configure-cache-listener
+ configure-cache-filter
+ configure-cache-store-by
+ runtime-cache-types
+ infinispan-eviction
+ infinispan-externalizer
+ infinispan-transaction-mode
+ infinispan-transaction-isolation
+
+
+
+
+
+ org.infinispan
+ infinispan-bom
+ ${version.infinispan}
+ pom
+ import
+
+
+
+
+
diff --git a/jcache/runtime-cache-types/pom.xml b/jcache/runtime-cache-types/pom.xml
new file mode 100644
index 00000000..576583c8
--- /dev/null
+++ b/jcache/runtime-cache-types/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.jcache
+ jcache-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ runtime-cache-types
+
diff --git a/jcache/runtime-cache-types/src/main/java/org/javaee8/jcache/runtime/KeyValueService.java b/jcache/runtime-cache-types/src/main/java/org/javaee8/jcache/runtime/KeyValueService.java
new file mode 100644
index 00000000..8ba0412a
--- /dev/null
+++ b/jcache/runtime-cache-types/src/main/java/org/javaee8/jcache/runtime/KeyValueService.java
@@ -0,0 +1,49 @@
+package org.javaee8.jcache.runtime;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.spi.CachingProvider;
+
+
+/**
+ * @author Radim Hanus
+ */
+public class KeyValueService {
+ private static final String CACHE_NAME = "cache.default";
+
+ private CacheManager cacheManager;
+
+ @PostConstruct
+ void init() {
+ CachingProvider cachingProvider = Caching.getCachingProvider();
+ cacheManager = cachingProvider.getCacheManager();
+
+ MutableConfiguration config = new MutableConfiguration<>();
+
+ // expected types of cache key and value
+ config.setTypes(String.class, String.class);
+
+ cacheManager.createCache(CACHE_NAME, config);
+ }
+
+ @PreDestroy
+ void destroy() {
+ cacheManager.close();
+ }
+
+ public void put(String key, String value) {
+ // checks both key and value types are the same as configured
+ Cache cache = cacheManager.getCache(CACHE_NAME, String.class, String.class);
+ cache.put(key, value);
+ }
+
+ public void put(Integer key, Integer value) {
+ // key and value types mismatch, should throw a runtime exception
+ Cache cache = cacheManager.getCache(CACHE_NAME, Integer.class, Integer.class);
+ cache.put(key, value);
+ }
+}
diff --git a/jcache/runtime-cache-types/src/test/java/org/javaee8/jcache/runtime/KeyValueServiceTest.java b/jcache/runtime-cache-types/src/test/java/org/javaee8/jcache/runtime/KeyValueServiceTest.java
new file mode 100644
index 00000000..eec75133
--- /dev/null
+++ b/jcache/runtime-cache-types/src/test/java/org/javaee8/jcache/runtime/KeyValueServiceTest.java
@@ -0,0 +1,50 @@
+package org.javaee8.jcache.runtime;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+
+import static org.hamcrest.CoreMatchers.either;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+
+/**
+ * @author Radim Hanus
+ */
+@RunWith(Arquillian.class)
+public class KeyValueServiceTest {
+ @Deployment
+ public static Archive> deploy() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(KeyValueService.class)
+ .addAsWebInfResource("beans.xml")
+ .addAsWebInfResource("jboss-deployment-structure.xml");
+ }
+
+ @Inject
+ private KeyValueService service;
+
+ @Test
+ public void test() throws Exception {
+ // available in cache
+ service.put("JSR107", "JCACHE");
+ }
+
+ @Test
+ public void testIllegalTypes() throws Exception {
+ try {
+ service.put(1, 10);
+ fail();
+ } catch (Exception e) {
+ assertThat(e, either(instanceOf(IllegalArgumentException.class)).or(instanceOf(ClassCastException.class)));
+ }
+ }
+}
diff --git a/jcache/runtime-cache-types/src/test/resources/beans.xml b/jcache/runtime-cache-types/src/test/resources/beans.xml
new file mode 100644
index 00000000..ae366cab
--- /dev/null
+++ b/jcache/runtime-cache-types/src/test/resources/beans.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/jcache/runtime-cache-types/src/test/resources/jboss-deployment-structure.xml b/jcache/runtime-cache-types/src/test/resources/jboss-deployment-structure.xml
new file mode 100644
index 00000000..3171299a
--- /dev/null
+++ b/jcache/runtime-cache-types/src/test/resources/jboss-deployment-structure.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jsonb/mapping-object/pom.xml b/jsonb/mapping-object/pom.xml
new file mode 100644
index 00000000..55711290
--- /dev/null
+++ b/jsonb/mapping-object/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.javaee8.json-b
+ json-b-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ mapping-object
+
diff --git a/jsonb/mapping-object/src/main/java/org/javaee8/jsonb/mapping/Dog.java b/jsonb/mapping-object/src/main/java/org/javaee8/jsonb/mapping/Dog.java
new file mode 100644
index 00000000..7b41de5c
--- /dev/null
+++ b/jsonb/mapping-object/src/main/java/org/javaee8/jsonb/mapping/Dog.java
@@ -0,0 +1,67 @@
+package org.javaee8.jsonb.mapping;
+
+import java.util.Objects;
+
+
+public class Dog {
+ private String name;
+ private int age;
+ private boolean bitable;
+
+ public Dog() {
+ }
+
+ public Dog(String name, int age, boolean bitable) {
+ this.name = name;
+ this.age = age;
+ this.bitable = bitable;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Dog dog = (Dog) o;
+ return age == dog.age &&
+ bitable == dog.bitable &&
+ Objects.equals(name, dog.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, age, bitable);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public boolean isBitable() {
+ return bitable;
+ }
+
+ public void setBitable(boolean bitable) {
+ this.bitable = bitable;
+ }
+
+ @Override
+ public String toString() {
+ return "Dog{" +
+ "name='" + name + '\'' +
+ ", age=" + age +
+ ", bitable=" + bitable +
+ '}';
+ }
+}
diff --git a/jsonb/mapping-object/src/test/java/org/javaee8/jsonb/mapping/DogTest.java b/jsonb/mapping-object/src/test/java/org/javaee8/jsonb/mapping/DogTest.java
new file mode 100644
index 00000000..a59bd616
--- /dev/null
+++ b/jsonb/mapping-object/src/test/java/org/javaee8/jsonb/mapping/DogTest.java
@@ -0,0 +1,48 @@
+package org.javaee8.jsonb.mapping;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.resolver.api.maven.Maven;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.json.bind.Jsonb;
+import javax.json.bind.JsonbBuilder;
+import java.io.File;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+
+@RunWith(Arquillian.class)
+public class DogTest {
+ @Deployment
+ public static Archive> deploy() {
+ File[] files = Maven.resolver().loadPomFromFile("pom.xml").importRuntimeDependencies()
+ .resolve().withoutTransitivity().asFile();
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(Dog.class)
+ .addAsLibraries(files);
+ }
+
+ @Test
+ public void test() throws Exception {
+ // json text of dog instance
+ String jsonDog = "{\"name\":\"Falco\",\"age\":4,\"bitable\":false}";
+ // dog instance
+ Dog dog = new Dog("Falco", 4, false);
+
+ // create Jsonb and serialize
+ Jsonb jsonb = JsonbBuilder.create();
+
+ // deserialize test
+ Dog deserializedDog = jsonb.fromJson(jsonDog, Dog.class);
+ assertThat(dog, equalTo(deserializedDog));
+ // serialization test
+ String serializedDog = jsonb.toJson(dog);
+ assertThat(deserializedDog, equalTo(jsonb.fromJson(serializedDog, Dog.class)));
+ }
+}
diff --git a/jsonb/pom.xml b/jsonb/pom.xml
new file mode 100644
index 00000000..08b9e53d
--- /dev/null
+++ b/jsonb/pom.xml
@@ -0,0 +1,60 @@
+
+
+ 4.0.0
+
+
+ org.javaee8
+ javaee8-samples
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ org.javaee8.json-b
+ json-b-samples
+ 1.0-SNAPSHOT
+ pom
+ JSR 367: JSON-B Samples
+
+
+ 1.0-SNAPSHOT
+ 1.0-SNAPSHOT
+ 1.1.0-SNAPSHOT
+
+
+
+ mapping-object
+
+
+
+
+ java.net-Public
+ Maven Java Net Snapshots and Releases
+ https://maven.java.net/content/groups/public/
+
+
+ yasson-snapshots
+ Yasson Snapshots repository
+ https://repo.eclipse.org/content/repositories/yasson-snapshots
+
+
+
+
+
+ javax.json.bind
+ javax.json.bind-api
+ ${version.javax.json.bind-api}
+
+
+ org.eclipse
+ yasson
+ ${version.yasson}
+
+
+ org.glassfish
+ javax.json
+ ${version.glassfish.javax.json}
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 541a37c9..96a24976 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,6 +11,8 @@
1.8
3.0.0
+ 1.8
+ 1.8
UTF-8
1.3.1
@@ -23,6 +25,8 @@
cdi
+ jcache
+ jsonb
@@ -30,7 +34,7 @@
org.jboss.arquillian
arquillian-bom
- 1.1.5.Final
+ 1.1.12.Final
import
pom
@@ -38,28 +42,97 @@
+
+
+
+
+
+ javax.inject
+ javax.inject
+ 1
+ provided
+
+
+ javax.interceptor
+ javax.interceptor-api
+ 1.2
provided
-
- org.jboss.weld
- weld-api
- 3.0.Alpha3
+ javax.transaction
+ javax.transaction-api
+ 1.2
+ provided
+
+
+ javax.enterprise.concurrent
+ javax.enterprise.concurrent-api
+ 1.0
provided
-
+
+
+ javax.annotation
+ javax.annotation-api
+ 1.3
+ provided
+
+
+
+
+
+ javax.enterprise
+ cdi-api
+ 2.0.Beta1
+ provided
+
+
+ javax.el
+ javax.el-api
+
+
+ javax.interceptor
+ javax.interceptor-api
+
+
+
+
+
+
+ javax.cache
+ cache-api
+ 1.0.0
+ provided
+
+
junit
junit
- 4.11
+ 4.12
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+ 1.3
test
+
+ org.hamcrest
+ hamcrest-library
+ 1.3
+ test
+
+
org.jboss.arquillian.junit
arquillian-junit-container
@@ -89,26 +162,16 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.1
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 2.17
-
-
- default-test
- test
-
- test
-
-
-
+ 3.5.1
+
+ ${java.min.version}
+ ${java.min.version}
+
org.apache.maven.plugins
maven-surefire-report-plugin
- 2.17
+ 2.19.1
true
true
@@ -117,18 +180,24 @@
org.apache.maven.plugins
maven-war-plugin
- 2.5
+ 3.0.0
+
+ true
+ false
+
maven-enforcer-plugin
- At least Maven in version ${maven.min.version} is required.
+ At least Maven in version ${maven.min.version} is
+ required.
${maven.min.version}
- At least a JDK in version ${java.min.version} is required.
+ At least a JDK in version ${java.min.version} is
+ required.
${java.min.version}
@@ -163,7 +232,7 @@
org.apache.maven.plugins
maven-surefire-report-plugin
- 2.18
+ 2.19.1
true
true
@@ -180,34 +249,58 @@
true
+
+
+
+
+
+
+
+ org.jboss.logging
+ jboss-logging
+ 3.3.0.Final
+ test
+
+
+
+
+-->
+
+
- org.wildfly
+ org.wildfly.arquillian
wildfly-arquillian-container-remote
- 8.2.0.Final
+ 2.0.0.Final
test