You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by pa...@apache.org on 2017/03/13 10:35:24 UTC

[32/50] [abbrv] polygene-java git commit: New (de)serialization API and SPI & new implementations

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/mixin/JDKMixinTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/mixin/JDKMixinTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/mixin/JDKMixinTest.java
index 116e82c..fc4937a 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/mixin/JDKMixinTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/mixin/JDKMixinTest.java
@@ -26,6 +26,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
 import org.apache.polygene.api.common.Visibility;
 import org.apache.polygene.api.concern.Concerns;
 import org.apache.polygene.api.concern.GenericConcern;
@@ -36,7 +39,6 @@ import org.apache.polygene.api.service.ServiceReference;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.test.AbstractPolygeneTest;
-import org.json.JSONObject;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -46,56 +48,46 @@ import static org.junit.Assert.assertThat;
 /**
  * Assert that JDK classes are usable as Mixins.
  */
-public class JDKMixinTest
-    extends AbstractPolygeneTest
+public class JDKMixinTest extends AbstractPolygeneTest
 {
-
     @Concerns( JDKMixinConcern.class )
-    public interface JSONSerializableMap
-        extends Map<String, String>
+    public interface JSONSerializableMap extends Map<String, String>
     {
-
-        JSONObject toJSON();
-
+        JsonObject toJSON();
     }
 
     @SuppressWarnings( "serial" )
-    public static class ExtendsJDKMixin
-        extends HashMap<String, String>
+    public static class ExtendsJDKMixin extends HashMap<String, String>
         implements JSONSerializableMap
     {
-
         @Override
-        public JSONObject toJSON()
+        public JsonObject toJSON()
         {
             System.out.println( ">>>> Call ExtendsJDKMixin.toJSON()" );
-            // Copy the Map before handing it to JSONObject so that the JSONObject do not use the Composite
-            return new JSONObject( new HashMap<String, String>( this ) );
+            JsonObjectBuilder builder = Json.createObjectBuilder();
+            entrySet().forEach( entry -> builder.add( entry.getKey(), entry.getValue() ) );
+            return builder.build();
         }
-
     }
 
     public static abstract class ComposeWithJDKMixin
         implements JSONSerializableMap
     {
-
         @This
         private Map<String, String> map;
 
         @Override
-        public JSONObject toJSON()
+        public JsonObject toJSON()
         {
             System.out.println( ">>>> Call ComposeWithJDKMixin.toJSON()" );
-            // Copy the Map before handing it to JSONObject so that the JSONObject do not use the Composite
-            return new JSONObject( new HashMap<String, String>( map ) );
+            JsonObjectBuilder builder = Json.createObjectBuilder();
+            map.entrySet().forEach( entry -> builder.add( entry.getKey(), entry.getValue() ) );
+            return builder.build();
         }
-
     }
 
-    public static class JDKMixinConcern
-        extends GenericConcern
+    public static class JDKMixinConcern extends GenericConcern
     {
-
         @Override
         public Object invoke( Object proxy, Method method, Object[] args )
             throws Throwable
@@ -104,13 +96,14 @@ public class JDKMixinTest
             CONCERN_RECORDS.add( method.getName() );
             return next.invoke( proxy, method, args );
         }
-
     }
 
     private static final Identity EXTENDS_IDENTITY = new StringIdentity( ExtendsJDKMixin.class.getName() );
     private static final Identity COMPOSE_IDENTITY = new StringIdentity( ComposeWithJDKMixin.class.getName() );
-    private static final Predicate<ServiceReference<?>> EXTENDS_IDENTITY_SPEC = new ServiceIdentitySpec( EXTENDS_IDENTITY );
-    private static final Predicate<ServiceReference<?>> COMPOSE_IDENTITY_SPEC = new ServiceIdentitySpec( COMPOSE_IDENTITY );
+    private static final Predicate<ServiceReference<?>> EXTENDS_IDENTITY_SPEC = new ServiceIdentitySpec(
+        EXTENDS_IDENTITY );
+    private static final Predicate<ServiceReference<?>> COMPOSE_IDENTITY_SPEC = new ServiceIdentitySpec(
+        COMPOSE_IDENTITY );
     private static final List<String> CONCERN_RECORDS = new ArrayList<String>();
 
     @Before
@@ -123,16 +116,16 @@ public class JDKMixinTest
     public void assemble( ModuleAssembly module )
         throws AssemblyException
     {
-        module.services( JSONSerializableMap.class ).
-            identifiedBy( EXTENDS_IDENTITY.toString() ).
-            withMixins( ExtendsJDKMixin.class ).
-            instantiateOnStartup();
-
-        module.layer().module( "compose" ).services( JSONSerializableMap.class ).
-            visibleIn( Visibility.layer ).
-            identifiedBy( COMPOSE_IDENTITY.toString() ).
-            withMixins( HashMap.class, ComposeWithJDKMixin.class ).
-            instantiateOnStartup();
+        module.services( JSONSerializableMap.class )
+              .identifiedBy( EXTENDS_IDENTITY.toString() )
+              .withMixins( ExtendsJDKMixin.class )
+              .instantiateOnStartup();
+
+        module.layer().module( "compose" ).services( JSONSerializableMap.class )
+              .visibleIn( Visibility.layer )
+              .identifiedBy( COMPOSE_IDENTITY.toString() )
+              .withMixins( HashMap.class, ComposeWithJDKMixin.class )
+              .instantiateOnStartup();
     }
 
     @Test
@@ -147,12 +140,12 @@ public class JDKMixinTest
 
         JSONSerializableMap extending = services.get( 0 ).get();
         extending.put( "foo", "bar" ); // Concern trigger #1 (put)
-        JSONObject json = extending.toJSON(); // Concern trigger #2, #3 and #4 (toJSON, size, entrySet)
+        JsonObject json = extending.toJSON(); // Concern trigger #2 and #3 (toJSON, entrySet)
 
-        assertThat( json.length(), equalTo( 1 ) );
-        assertThat( json.optString( "foo" ), equalTo( "bar" ) );
+        assertThat( json.size(), equalTo( 1 ) );
+        assertThat( json.getString( "foo" ), equalTo( "bar" ) );
 
-        assertThat( CONCERN_RECORDS.size(), equalTo( 4 ) );
+        assertThat( CONCERN_RECORDS.size(), equalTo( 3 ) );
     }
 
     @Test
@@ -167,21 +160,20 @@ public class JDKMixinTest
 
         JSONSerializableMap composing = services.get( 0 ).get();
         composing.put( "foo", "bar" ); // Concern trigger #1 (put)
-        JSONObject json = composing.toJSON(); // Concern trigger #2, #3 and #4 (toJSON, size, entrySet)
+        JsonObject json = composing.toJSON(); // Concern trigger #2 and #3 (toJSON, entrySet)
 
-        assertThat( json.length(), equalTo( 1 ) );
-        assertThat( json.optString( "foo" ), equalTo( "bar" ) );
+        assertThat( json.size(), equalTo( 1 ) );
+        assertThat( json.getString( "foo" ), equalTo( "bar" ) );
 
-        assertThat( CONCERN_RECORDS.size(), equalTo( 4 ) );
+        assertThat( CONCERN_RECORDS.size(), equalTo( 3 ) );
     }
 
     private static class ServiceIdentitySpec
         implements Predicate<ServiceReference<?>>
     {
-
         private final Identity identity;
 
-        ServiceIdentitySpec(Identity identity)
+        ServiceIdentitySpec( Identity identity )
         {
             this.identity = identity;
         }
@@ -191,7 +183,5 @@ public class JDKMixinTest
         {
             return item.identity().equals( identity );
         }
-
     }
-
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/property/ValueNestedBuilderTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/property/ValueNestedBuilderTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/property/ValueNestedBuilderTest.java
index caad29d..026cb13 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/property/ValueNestedBuilderTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/property/ValueNestedBuilderTest.java
@@ -30,13 +30,11 @@ import org.apache.polygene.api.value.ValueComposite;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.test.AbstractPolygeneTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
 import org.junit.Test;
 
 public class ValueNestedBuilderTest
     extends AbstractPolygeneTest
 {
-
     private interface InnerValue
         extends ValueComposite
     {
@@ -75,7 +73,6 @@ public class ValueNestedBuilderTest
     public void assemble( ModuleAssembly module )
         throws AssemblyException
     {
-        module.services( OrgJsonValueSerializationService.class );
         module.values( InnerValue.class, InnerDefaultedValue.class, OuterValue.class, OuterDefaultedValue.class );
     }
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/value/AssociationToValueTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/value/AssociationToValueTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/value/AssociationToValueTest.java
index 370883f..18b6935 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/value/AssociationToValueTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/value/AssociationToValueTest.java
@@ -35,12 +35,10 @@ import org.apache.polygene.api.unitofwork.UnitOfWork;
 import org.apache.polygene.api.unitofwork.UnitOfWorkFactory;
 import org.apache.polygene.api.unitofwork.concern.UnitOfWorkConcern;
 import org.apache.polygene.api.unitofwork.concern.UnitOfWorkPropagation;
-import org.apache.polygene.api.value.ValueSerialization;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
 import org.apache.polygene.test.AbstractPolygeneTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
 import org.junit.Test;
 
 import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
@@ -102,7 +100,6 @@ public class AssociationToValueTest extends AbstractPolygeneTest
         module.entities( Person.class );
         module.values( Person.class );
         module.services( PersonRepository.class ).withConcerns( UnitOfWorkConcern.class );
-        module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON );
         module.services( MemoryEntityStoreService.class );
 
         module.services( Runnable.class )

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/value/NestedValueBuilderTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/value/NestedValueBuilderTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/value/NestedValueBuilderTest.java
index 55196cb..45859de 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/value/NestedValueBuilderTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/value/NestedValueBuilderTest.java
@@ -23,8 +23,6 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
-import org.junit.Test;
 import org.apache.polygene.api.common.UseDefaults;
 import org.apache.polygene.api.property.Property;
 import org.apache.polygene.api.value.ValueBuilder;
@@ -32,6 +30,7 @@ import org.apache.polygene.api.value.ValueComposite;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.test.AbstractPolygeneTest;
+import org.junit.Test;
 
 import static org.junit.Assert.fail;
 
@@ -78,7 +77,6 @@ public class NestedValueBuilderTest
     public void assemble( ModuleAssembly module )
         throws AssemblyException
     {
-        module.services( OrgJsonValueSerializationService.class );
         module.values( InnerValue.class, InnerDefaultedValue.class, OuterValue.class, OuterDefaultedValue.class );
     }
 
@@ -87,8 +85,8 @@ public class NestedValueBuilderTest
     {
         ValueBuilder<InnerValue> innerBuilder = valueBuilderFactory.newValueBuilder( InnerValue.class );
         InnerValue inner = innerBuilder.prototype();
-        inner.listProp().set( new ArrayList<String>() );
-        inner.mapProp().set( new HashMap<String, String>() );
+        inner.listProp().set( new ArrayList<>() );
+        inner.mapProp().set( new HashMap<>() );
         inner = innerBuilder.newInstance();
         // If we reach this point, value creation went well
         try
@@ -116,12 +114,12 @@ public class NestedValueBuilderTest
     {
         ValueBuilder<InnerValue> innerBuilder = valueBuilderFactory.newValueBuilder( InnerValue.class );
         InnerValue innerPrototype = innerBuilder.prototype();
-        innerPrototype.listProp().set( new ArrayList<String>() );
-        innerPrototype.mapProp().set( new HashMap<String, String>() );
+        innerPrototype.listProp().set( new ArrayList<>() );
+        innerPrototype.mapProp().set( new HashMap<>() );
         InnerValue innerInstance = innerBuilder.newInstance();
         ValueBuilder<OuterValue> outerBuilder = valueBuilderFactory.newValueBuilder( OuterValue.class );
         OuterValue outerPrototype = outerBuilder.prototype();
-        List<InnerValue> inners = new ArrayList<InnerValue>();
+        List<InnerValue> inners = new ArrayList<>();
         inners.add( innerInstance );
         outerPrototype.innerListProp().set( inners );
         OuterValue outerInstance = outerBuilder.newInstance();
@@ -171,7 +169,7 @@ public class NestedValueBuilderTest
         InnerDefaultedValue innerInstance = innerBuilder.newInstance();
         ValueBuilder<OuterDefaultedValue> outerBuilder = valueBuilderFactory.newValueBuilder( OuterDefaultedValue.class );
         OuterDefaultedValue outerPrototype = outerBuilder.prototype();
-        List<InnerDefaultedValue> inners = new ArrayList<InnerDefaultedValue>();
+        List<InnerDefaultedValue> inners = new ArrayList<>();
         inners.add( innerInstance );
         outerPrototype.innerListPropDefault().set( inners );
         OuterDefaultedValue outerInstance = outerBuilder.newInstance();

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueCompositeBasicsTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueCompositeBasicsTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueCompositeBasicsTest.java
index 2ad6db4..bc538f1 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueCompositeBasicsTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueCompositeBasicsTest.java
@@ -19,15 +19,14 @@
  */
 package org.apache.polygene.runtime.value;
 
-import org.apache.polygene.test.AbstractPolygeneTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
-import org.junit.Test;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.mixin.Mixins;
 import org.apache.polygene.api.property.Property;
 import org.apache.polygene.api.value.ValueBuilder;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.test.AbstractPolygeneTest;
+import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -39,7 +38,6 @@ public class ValueCompositeBasicsTest
     public void assemble( ModuleAssembly module )
         throws AssemblyException
     {
-        module.services( OrgJsonValueSerializationService.class );
         module.values( SomeValue.class );
     }
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueSerializationRegressionTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueSerializationRegressionTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueSerializationRegressionTest.java
index 5143909..fe8cdd8 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueSerializationRegressionTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueSerializationRegressionTest.java
@@ -19,21 +19,19 @@
  */
 package org.apache.polygene.runtime.value;
 
-import org.apache.polygene.api.identity.HasIdentity;
-import org.apache.polygene.api.identity.StringIdentity;
-import org.junit.Test;
 import org.apache.polygene.api.association.Association;
 import org.apache.polygene.api.association.ManyAssociation;
 import org.apache.polygene.api.association.NamedAssociation;
+import org.apache.polygene.api.identity.HasIdentity;
+import org.apache.polygene.api.identity.StringIdentity;
 import org.apache.polygene.api.property.Property;
 import org.apache.polygene.api.unitofwork.UnitOfWorkCompletionException;
 import org.apache.polygene.api.value.ValueBuilder;
-import org.apache.polygene.api.value.ValueSerialization;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
 import org.apache.polygene.test.AbstractPolygeneTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
+import org.junit.Test;
 
 public class ValueSerializationRegressionTest extends AbstractPolygeneTest
 {
@@ -45,7 +43,6 @@ public class ValueSerializationRegressionTest extends AbstractPolygeneTest
         module.entities( DualFaced.class );
         module.values( DualFaced.class );
         module.services( MemoryEntityStoreService.class );
-        module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON );
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueWithAssociationTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueWithAssociationTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueWithAssociationTest.java
index 175e116..4441a76 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueWithAssociationTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueWithAssociationTest.java
@@ -19,10 +19,6 @@
  */
 package org.apache.polygene.runtime.value;
 
-import org.apache.polygene.api.identity.HasIdentity;
-import org.apache.polygene.api.identity.Identity;
-import org.apache.polygene.api.identity.StringIdentity;
-import org.junit.Test;
 import org.apache.polygene.api.association.Association;
 import org.apache.polygene.api.association.AssociationStateHolder;
 import org.apache.polygene.api.association.ManyAssociation;
@@ -31,16 +27,18 @@ import org.apache.polygene.api.common.Optional;
 import org.apache.polygene.api.entity.EntityBuilder;
 import org.apache.polygene.api.entity.EntityComposite;
 import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.identity.HasIdentity;
+import org.apache.polygene.api.identity.Identity;
+import org.apache.polygene.api.identity.StringIdentity;
 import org.apache.polygene.api.property.Property;
 import org.apache.polygene.api.unitofwork.UnitOfWork;
 import org.apache.polygene.api.unitofwork.UnitOfWorkCompletionException;
 import org.apache.polygene.api.value.ValueBuilder;
-import org.apache.polygene.api.value.ValueSerialization;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
 import org.apache.polygene.test.AbstractPolygeneTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
+import org.junit.Test;
 
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.junit.Assert.assertThat;
@@ -56,7 +54,6 @@ public class ValueWithAssociationTest extends AbstractPolygeneTest
         module.values( SimpleName.class );
         module.values( DualFaced.class );
         module.services( MemoryEntityStoreService.class );
-        module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON );
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/visibility/VisibilityInUnitOfWorkTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/visibility/VisibilityInUnitOfWorkTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/visibility/VisibilityInUnitOfWorkTest.java
index b7dfe66..66c4bc8 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/visibility/VisibilityInUnitOfWorkTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/visibility/VisibilityInUnitOfWorkTest.java
@@ -30,7 +30,6 @@ import org.apache.polygene.api.structure.Application;
 import org.apache.polygene.api.structure.Module;
 import org.apache.polygene.api.unitofwork.UnitOfWork;
 import org.apache.polygene.api.unitofwork.UnitOfWorkFactory;
-import org.apache.polygene.api.value.ValueSerialization;
 import org.apache.polygene.bootstrap.ApplicationAssembly;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.Energy4Java;
@@ -38,7 +37,6 @@ import org.apache.polygene.bootstrap.LayerAssembly;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.bootstrap.unitofwork.DefaultUnitOfWorkAssembler;
 import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
 import org.junit.Test;
 
 public class VisibilityInUnitOfWorkTest
@@ -155,9 +153,6 @@ public class VisibilityInUnitOfWorkTest
             yourModule.services( YourService.class ).visibleIn( Visibility.layer );
             new DefaultUnitOfWorkAssembler().assemble( yourModule );
             infraModule.services( MemoryEntityStoreService.class ).visibleIn( Visibility.layer );
-            infraModule.services( OrgJsonValueSerializationService.class )
-                .visibleIn( Visibility.layer )
-                .taggedWith( ValueSerialization.Formats.JSON );
             new DefaultUnitOfWorkAssembler().assemble( infraModule );
             return appAssembly;
         } );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/test/performance/entitystore/memory/MemoryEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/test/performance/entitystore/memory/MemoryEntityStoreTest.java b/core/runtime/src/test/java/org/apache/polygene/test/performance/entitystore/memory/MemoryEntityStoreTest.java
index ce4b878..25c4a1b 100644
--- a/core/runtime/src/test/java/org/apache/polygene/test/performance/entitystore/memory/MemoryEntityStoreTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/test/performance/entitystore/memory/MemoryEntityStoreTest.java
@@ -20,14 +20,12 @@
 
 package org.apache.polygene.test.performance.entitystore.memory;
 
-import org.apache.polygene.api.value.ValueSerialization;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
 import org.apache.polygene.spi.entity.EntityState;
 import org.apache.polygene.spi.entitystore.StateChangeListener;
 import org.apache.polygene.test.entity.AbstractEntityStoreTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
 
 import static org.apache.polygene.bootstrap.ImportedServiceDeclaration.NEW_OBJECT;
 
@@ -44,7 +42,6 @@ public class MemoryEntityStoreTest
         super.assemble( module );
 
         module.services( MemoryEntityStoreService.class );
-        module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON );
         module.importedServices( StatePrinter.class ).importedBy( NEW_OBJECT );
         module.objects( StatePrinter.class );
     }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/build.gradle
----------------------------------------------------------------------
diff --git a/core/spi/build.gradle b/core/spi/build.gradle
index b6240e9..605d3c7 100644
--- a/core/spi/build.gradle
+++ b/core/spi/build.gradle
@@ -24,7 +24,9 @@ jar { manifest { name = "Apache Polygene\u2122 Core SPI" } }
 
 dependencies {
   api polygene.core.api
-  api libraries.org_json
+  api libraries.javax_json
+
+  runtimeOnly libraries.johnzon
 
   testImplementation polygene.core.testsupport
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/docs/serialization.txt
----------------------------------------------------------------------
diff --git a/core/spi/src/docs/serialization.txt b/core/spi/src/docs/serialization.txt
new file mode 100644
index 0000000..dca8955
--- /dev/null
+++ b/core/spi/src/docs/serialization.txt
@@ -0,0 +1,83 @@
+///////////////////////////////////////////////////////////////
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+///////////////////////////////////////////////////////////////
+
+[[core-spi-serialization,Serialization SPI]]
+= Serialization SPI =
+
+== Overview ==
+
+The Polygene\u2122 Core Runtime use Serialization to provide string representation of ValueComposites via their `toString()`
+method, and, their instantiation from the very same representation via the `newValueFromSerializedState(..)` method of
+the ValueBuilderFactory API.
+
+In each Module, if no Serialization service is assembled, a default one supporting the JSON format is used.
+
+// TODO Add sample usage of the Serialization service
+
+== Implementation notes ==
+
+Simply implement Serialization to create an extension for the Serialization SPI.
+The Core SPI module provides adapters to create pull-parsing capable Serializers and pull-parsing and tree-parsing
+capable Deserializers.
+
+The behaviour described here apply to all Serialization services implemented using the Core SPI adapters. Note that
+nothing stops you from implementing an extension for the Serialization SPI without relying on theses adapters.
+
+Theses adapters are tailored for serialization mechanisms that support the following two structures that can be nested:
+
+    * a collection of name/value pairs. In various languages, this is realized as an object, record, struct,
+      dictionary, hash table, keyed list, or associative array,
+    * an ordered list of values. In most languages, this is realized as an array, vector, list, or sequence ;
+
+in other words, a JSON-like structure.
+
+Special attention is taken when dealing with Maps. They are serialized as an ordered list of collections of
+name/value pairs to keep the Map order for least surprise. That way, even when the underlying serialization mechanism
+do not keep the collection of name/value pairs order we can rely on it being kept.
+
+Here is a sample Map with two entries in JSON notation to make things clear:
+
+[source,javascript]
+----
+[
+    { "key": "foo",       "value": "bar"   },
+    { "key": "cathedral", "value": "bazar" }
+]
+----
+
+Among Plain Values (see the <<core-api-value,Serialization API>> section) some are considered primitives to
+underlying serialization mechanisms and by so handed/come without conversion to/from implementations.
+
+Primitive values can be one of:
+
+    * String,
+    * Boolean or boolean,
+    * Integer or int,
+    * Long or long,
+    * Short or short,
+    * Byte or byte,
+    * Float or float,
+    * Double or double.
+
+Serialization is always done in a streaming manner using a pull-parsing based approach.
+
+Deserialization is done in a streaming manner using a pull-parsing based approach except when encountering a
+ValueComposite. ValueComposite types are deserialized using a tree-parsing based approach.
+
+All this means that you can serialize and deserialize large collections of values without filling the heap.

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/docs/spi.txt
----------------------------------------------------------------------
diff --git a/core/spi/src/docs/spi.txt b/core/spi/src/docs/spi.txt
index 3980412..9371827 100644
--- a/core/spi/src/docs/spi.txt
+++ b/core/spi/src/docs/spi.txt
@@ -32,7 +32,7 @@ include::../../build/docs/buildinfo/artifact.txt[]
 
 There are currently 5 Core SPI extensions;
 
-    * <<core-spi-valueserialization>>
+    * <<core-spi-serialization>>
     * <<core-spi-entitystore>>
     * <<core-spi-cache>>
     * <<core-spi-indexing>>
@@ -45,7 +45,7 @@ can be solved in a support manner, or that we need to extend the Core API to sup
 
 :leveloffset: {level3}
 
-include::valueserialization.txt[]
+include::serialization.txt[]
 
 :leveloffset: {level3}
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/docs/valueserialization.txt
----------------------------------------------------------------------
diff --git a/core/spi/src/docs/valueserialization.txt b/core/spi/src/docs/valueserialization.txt
deleted file mode 100644
index 9f76b73..0000000
--- a/core/spi/src/docs/valueserialization.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-///////////////////////////////////////////////////////////////
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
-///////////////////////////////////////////////////////////////
-
-[[core-spi-valueserialization,ValueSerialization SPI]]
-= ValueSerialization SPI =
-
-== Overview ==
-
-The Polygene\u2122 Core Runtime use ValueSerialization to provide string representation of ValueComposites via their `toString()`
-method, and, their instanciation from the very same representation via the `newValueFromSerializedState(..)` method of
-the ValueBuilderFactory API.
-
-If no ValueSerialization service is visible, a default implementation supporting the JSON format used but note that it
-won't be available as a Service. So, in order to use the full ValueSerialization API a ValueSerialization service must
-be explicitely assembled in the Application. See the <<extensions>> documentation for details.
-
-== Implementation notes ==
-
-Simply implement ValueSerialization to create an extension for the ValueSerialization SPI.
-The Core SPI module provides adapters to create pull-parsing capable ValueSerializers and pull-parsing and tree-parsing
-capable ValueDeserializers.
-
-The behaviour described here apply to all ValueSerialization services implemented using the Core SPI adapters. Note that
-nothing stops you from implementing an extension for the ValueSerialization SPI without relying on theses adapters.
-
-Theses adapters are tailored for serialization mechanisms that support the following two structures that can be nested:
-
-    * a collection of name/value pairs. In various languages, this is realized as an object, record, struct,
-      dictionary, hash table, keyed list, or associative array,
-    * an ordered list of values. In most languages, this is realized as an array, vector, list, or sequence ;
-
-in other words, a JSON-like structure.
-
-Special attention is taken when dealing with Maps. They are serialized as an ordered list of collections of
-name/value pairs to keep the Map order for least surprise. That way, even when the underlying serialization mechanism
-do not keep the collection of name/value pairs order we can rely on it being kept.
-
-Here is a sample Map with two entries in JSON notation to make things clear:
-
-[source,javascript]
-----
-[
-    { "key": "foo",       "value": "bar"   },
-    { "key": "cathedral", "value": "bazar" }
-]
-----
-
-Among Plain Values (see the <<core-api-value,ValueSerialization API>> section) some are considered primitives to
-underlying serialization mechanisms and by so handed/come without conversion to/from implementations.
-
-Primitive values can be one of:
-
-    * String,
-    * Boolean or boolean,
-    * Integer or int,
-    * Long or long,
-    * Short or short,
-    * Byte or byte,
-    * Float or float,
-    * Double or double.
-
-Serialization is always done in a streaming manner using a pull-parsing based approach.
-
-Deserialization is done in a streaming manner using a pull-parsing based approach except when encountering a
-ValueComposite. ValueComposite types are deserialized using a tree-parsing based approach.
-
-All this means that you can serialize and deserialize large collections of values without filling the heap.

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/entitystore/memory/MemoryMapEntityStoreMixin.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/entitystore/memory/MemoryMapEntityStoreMixin.java b/core/spi/src/main/java/org/apache/polygene/entitystore/memory/MemoryMapEntityStoreMixin.java
index 7c343fa..98b4f8c 100644
--- a/core/spi/src/main/java/org/apache/polygene/entitystore/memory/MemoryMapEntityStoreMixin.java
+++ b/core/spi/src/main/java/org/apache/polygene/entitystore/memory/MemoryMapEntityStoreMixin.java
@@ -23,11 +23,11 @@ import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
-import java.io.UncheckedIOException;
 import java.io.Writer;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.stream.Stream;
+import javax.json.Json;
 import org.apache.polygene.api.entity.EntityDescriptor;
 import org.apache.polygene.api.entity.EntityReference;
 import org.apache.polygene.spi.entitystore.BackupRestore;
@@ -37,9 +37,6 @@ import org.apache.polygene.spi.entitystore.EntityStoreException;
 import org.apache.polygene.spi.entitystore.helpers.JSONKeys;
 import org.apache.polygene.spi.entitystore.helpers.MapEntityStore;
 import org.apache.polygene.spi.entitystore.helpers.MapEntityStoreActivation;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
 
 /**
  * In-memory implementation of MapEntityStore.
@@ -55,21 +52,15 @@ public class MemoryMapEntityStoreMixin
     }
 
     @Override
-    public void activateMapEntityStore()
-        throws Exception
-    {
-        // NOOP
-    }
+    public void activateMapEntityStore() {}
 
-    public boolean contains( EntityReference entityReference, EntityDescriptor descriptor )
-        throws EntityStoreException
+    public boolean contains( EntityReference entityReference, EntityDescriptor descriptor ) throws EntityStoreException
     {
         return store.containsKey( entityReference );
     }
 
     @Override
-    public Reader get( EntityReference entityReference )
-        throws EntityStoreException
+    public Reader get( EntityReference entityReference ) throws EntityStoreException
     {
         String state = store.get( entityReference );
         if( state == null )
@@ -81,8 +72,7 @@ public class MemoryMapEntityStoreMixin
     }
 
     @Override
-    public void applyChanges( MapEntityStore.MapChanges changes )
-        throws IOException
+    public void applyChanges( MapEntityStore.MapChanges changes ) throws Exception
     {
         changes.visitMap( new MemoryMapChanger() );
     }
@@ -100,29 +90,23 @@ public class MemoryMapEntityStoreMixin
     }
 
     @Override
-    public void restore( final Stream<String> stream )
+    public void restore( Stream<String> stream )
     {
         store.clear();
-        stream.forEach( item -> {
-            try
+        stream.forEach(
+            item ->
             {
-                JSONTokener tokener = new JSONTokener( item );
-                JSONObject entity = (JSONObject) tokener.nextValue();
-                String id = entity.getString( JSONKeys.IDENTITY );
+                String id = Json.createReader( new StringReader( item ) )
+                                .readObject().getString( JSONKeys.IDENTITY );
                 store.put( EntityReference.parseEntityReference( id ), item );
-            }
-            catch( JSONException e )
-            {
-                throw new UncheckedIOException( new IOException( e ) );
-            }
-        } );
+            } );
     }
 
     private class MemoryMapChanger
         implements MapChanger
     {
         @Override
-        public Writer newEntity( final EntityReference ref, EntityDescriptor descriptor )
+        public Writer newEntity( EntityReference ref, EntityDescriptor descriptor )
         {
             return new StringWriter( 1000 )
             {
@@ -142,7 +126,7 @@ public class MemoryMapEntityStoreMixin
         }
 
         @Override
-        public Writer updateEntity( final EntityReference ref, EntityDescriptor descriptor )
+        public Writer updateEntity( MapChange mapChange )
             throws IOException
         {
             return new StringWriter( 1000 )
@@ -152,11 +136,12 @@ public class MemoryMapEntityStoreMixin
                     throws IOException
                 {
                     super.close();
-                    String old = store.put( ref, toString() );
+                    EntityReference reference = mapChange.reference();
+                    String old = store.put( reference, toString() );
                     if( old == null )
                     {
-                        store.remove( ref );
-                        throw new EntityNotFoundException( ref );
+                        store.remove( reference );
+                        throw new EntityNotFoundException( reference );
                     }
                 }
             };

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJson.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJson.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJson.java
new file mode 100644
index 0000000..3c44864
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJson.java
@@ -0,0 +1,139 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.serialization.javaxjson;
+
+import java.util.Map;
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonString;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+
+/**
+ * javax.json utilities.
+ */
+public class JavaxJson
+{
+    /**
+     * Create a {@link JsonObjectBuilder} populated with the state of a {@link JsonObject}.
+     *
+     * @param jo the JsonObject
+     * @return the builder
+     */
+    public static JsonObjectBuilder toBuilder( JsonObject jo )
+    {
+        JsonObjectBuilder job = Json.createObjectBuilder();
+        for( Map.Entry<String, JsonValue> entry : jo.entrySet() )
+        {
+            job.add( entry.getKey(), entry.getValue() );
+        }
+        return job;
+    }
+
+    /**
+     * Create a {@link JsonArrayBuilder} populated with the state of a {@link JsonArray}.
+     *
+     * @param ja the JsonArray
+     * @return the builder
+     */
+    public static JsonArrayBuilder toBuilder( JsonArray ja )
+    {
+        JsonArrayBuilder job = Json.createArrayBuilder();
+        for( JsonValue value : ja )
+        {
+            job.add( value );
+        }
+        return job;
+    }
+
+    /**
+     * Create a {@link JsonString} from {@link Object#toString()}.
+     *
+     * @param object the Object
+     * @return the JsonString
+     */
+    public static JsonString toJsonString( Object object )
+    {
+        return Json.createObjectBuilder().add( "value", object.toString() ).build().getJsonString( "value" );
+    }
+
+    /**
+     * Get a {@link String} out of a {@link JsonValue}.
+     *
+     * @param jsonValue the JSON value
+     * @return the String
+     */
+    public static String asString( JsonValue jsonValue )
+    {
+        return jsonValue instanceof JsonString ? ( (JsonString) jsonValue ).getString() : jsonValue.toString();
+    }
+
+    /**
+     * Require a {@link JsonValue} to be a {@link JsonStructure}.
+     *
+     * @param json the JSON value
+     * @return the JSON structure
+     * @throws JsonException if it is not
+     */
+    public static JsonStructure requireJsonStructure( JsonValue json )
+    {
+        if( json.getValueType() != JsonValue.ValueType.OBJECT && json.getValueType() != JsonValue.ValueType.ARRAY )
+        {
+            throw new JsonException( "Expected a JSON object or array but got " + json );
+        }
+        return (JsonStructure) json;
+    }
+
+    /**
+     * Require a {@link JsonValue} to be a {@link JsonObject}.
+     *
+     * @param json the JSON value
+     * @return the JSON object
+     * @throws JsonException if it is not
+     */
+    public static JsonObject requireJsonObject( JsonValue json )
+    {
+        if( json.getValueType() != JsonValue.ValueType.OBJECT )
+        {
+            throw new JsonException( "Expected a JSON object but got " + json );
+        }
+        return (JsonObject) json;
+    }
+
+    /**
+     * Require a {@link JsonValue} to be a {@link JsonArray}.
+     *
+     * @param json the JSON value
+     * @return the JSON array
+     * @throws JsonException if it is not
+     */
+    public static JsonArray requireJsonArray( JsonValue json )
+    {
+        if( json.getValueType() != JsonValue.ValueType.ARRAY )
+        {
+            throw new JsonException( "Expected a JSON array but got " + json );
+        }
+        return (JsonArray) json;
+    }
+
+    private JavaxJson() {}
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapter.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapter.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapter.java
new file mode 100644
index 0000000..d8ffcfa
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapter.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.serialization.javaxjson;
+
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import javax.json.JsonValue;
+import org.apache.polygene.api.type.ValueType;
+
+/**
+ * Adapter for JSON (de)serialization.
+ *
+ * @param <T> the adapted type
+ */
+public interface JavaxJsonAdapter<T>
+{
+    /**
+     * @return the adapted type
+     */
+    Class<T> type();
+
+    /**
+     * Serialize.
+     *
+     * @param object Object to serialize, never null
+     * @param serializeFunction Serialization function for nested structure serialization
+     * @return Serialized JSON representation
+     */
+    JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction );
+
+    /**
+     * Deserialize.
+     *
+     * @param json JSON to deserialize from, never null
+     * @param deserializeFunction Deserialization function for nested structure deserialization
+     * @return Deserialized object
+     */
+    T deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction );
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapters.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapters.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapters.java
new file mode 100644
index 0000000..fdc9d27
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapters.java
@@ -0,0 +1,64 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.serialization.javaxjson;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.type.ValueType;
+
+import static org.apache.polygene.api.type.HasTypesCollectors.closestType;
+
+@Mixins( JavaxJsonAdapters.Mixin.class )
+public interface JavaxJsonAdapters
+{
+    void registerAdapter( ValueType valueType, JavaxJsonAdapter<?> adapter );
+
+    <T> JavaxJsonAdapter<T> adapterFor( ValueType valueType );
+
+    default <T> JavaxJsonAdapter<T> adapterFor( Class<T> type )
+    {
+        return adapterFor( ValueType.of( type ) );
+    }
+
+    class Mixin implements JavaxJsonAdapters
+    {
+        private Map<ValueType, JavaxJsonAdapter<?>> adapters = new LinkedHashMap<>();
+
+        @Override
+        public void registerAdapter( ValueType valueType, JavaxJsonAdapter<?> adapter )
+        {
+            adapters.put( valueType, adapter );
+        }
+
+        @Override
+        public <T> JavaxJsonAdapter<T> adapterFor( ValueType valueType )
+        {
+            return castAdapter( adapters.keySet().stream()
+                                        .collect( closestType( valueType ) )
+                                        .map( adapters::get )
+                                        .orElse( null ) );
+        }
+
+        @SuppressWarnings( "unchecked" )
+        private <T> JavaxJsonAdapter<T> castAdapter( JavaxJsonAdapter<?> adapter )
+        {
+            return (JavaxJsonAdapter<T>) adapter;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
new file mode 100644
index 0000000..721c884
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
@@ -0,0 +1,273 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.serialization.javaxjson;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+import org.apache.polygene.api.association.AssociationDescriptor;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.injection.scope.This;
+import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.property.PropertyDescriptor;
+import org.apache.polygene.api.serialization.SerializationException;
+import org.apache.polygene.api.service.ServiceDescriptor;
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.api.type.CollectionType;
+import org.apache.polygene.api.type.EnumType;
+import org.apache.polygene.api.type.MapType;
+import org.apache.polygene.api.type.ValueCompositeType;
+import org.apache.polygene.api.type.ValueType;
+import org.apache.polygene.api.value.ValueBuilder;
+import org.apache.polygene.api.value.ValueDescriptor;
+import org.apache.polygene.spi.serialization.AbstractTextDeserializer;
+import org.apache.polygene.spi.serialization.JsonDeserializer;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.Collections.unmodifiableList;
+import static java.util.Collections.unmodifiableMap;
+import static java.util.Collections.unmodifiableSet;
+import static java.util.stream.Collectors.toCollection;
+import static org.apache.polygene.api.util.Collectors.toMapWithNullValues;
+import static org.apache.polygene.serialization.javaxjson.JavaxJson.asString;
+import static org.apache.polygene.serialization.javaxjson.JavaxJson.requireJsonArray;
+import static org.apache.polygene.serialization.javaxjson.JavaxJson.requireJsonObject;
+import static org.apache.polygene.serialization.javaxjson.JavaxJson.requireJsonStructure;
+
+public class JavaxJsonDeserializer extends AbstractTextDeserializer implements JsonDeserializer
+{
+    @This
+    private JavaxJsonAdapters adapters;
+
+    @Uses
+    private ServiceDescriptor descriptor;
+
+    @Override
+    public <T> T fromJson( ModuleDescriptor module, ValueType valueType, JsonValue state )
+    {
+        return doDeserialize( module, valueType, state );
+    }
+
+    @SuppressWarnings( "unchecked" )
+    private <T> T doDeserialize( ModuleDescriptor module, ValueType valueType, JsonValue json )
+    {
+        if( json == null || JsonValue.NULL.equals( json ) )
+        {
+            return null;
+        }
+        JavaxJsonAdapter<?> adapter = adapters.adapterFor( valueType );
+        if( adapter != null )
+        {
+            return (T) adapter.deserialize( json, ( jsonValue, type ) -> doDeserialize( module, type, jsonValue ) );
+        }
+        Class<? extends ValueType> valueTypeClass = valueType.getClass();
+        if( EnumType.class.isAssignableFrom( valueTypeClass ) )
+        {
+            return (T) Enum.valueOf( (Class) valueType.primaryType(), asString( json ) );
+        }
+        if( CollectionType.class.isAssignableFrom( valueTypeClass ) )
+        {
+            return (T) deserializeCollection( module, (CollectionType) valueType, requireJsonArray( json ) );
+        }
+        if( MapType.class.isAssignableFrom( valueTypeClass ) )
+        {
+            return (T) deserializeMap( module, (MapType) valueType, requireJsonStructure( json ) );
+        }
+        if( ValueCompositeType.class.isAssignableFrom( valueTypeClass ) )
+        {
+            return (T) deserializeValueComposite( module, (ValueCompositeType) valueType, requireJsonObject( json ) );
+        }
+        return doGuessDeserialize( module, valueType, json );
+    }
+
+    @SuppressWarnings( "unchecked" )
+    private <T> T doGuessDeserialize( ModuleDescriptor module, ValueType valueType, JsonValue json )
+    {
+        switch( json.getValueType() )
+        {
+            case OBJECT:
+                JsonObject object = (JsonObject) json;
+                String typeInfo = object.getString( getTypeInfoPropertyName(), valueType.primaryType().getName() );
+                ValueDescriptor valueDescriptor = module.valueDescriptor( typeInfo );
+                if( valueDescriptor != null )
+                {
+                    return (T) deserializeValueComposite( module, valueDescriptor.valueType(), object );
+                }
+            case STRING:
+                return (T) deserializeBase64( asString( json ) );
+            default:
+                throw new SerializationException( "Don't know how to deserialize " + valueType + " from " + json );
+        }
+    }
+
+    private <T> Collection<T> deserializeCollection( ModuleDescriptor module, CollectionType collectionType,
+                                                     JsonArray json )
+    {
+        return (Collection<T>) json.stream()
+                                   .map( item -> doDeserialize( module, collectionType.collectedType(), item ) )
+                                   .collect( toCollection(
+                                       () -> collectionType.isSet() ? new LinkedHashSet<>() : new ArrayList<>() ) );
+    }
+
+    /**
+     * Map deserialization.
+     *
+     * {@literal JsonObject}s are deserialized to {@literal Map<String, ?>}.
+     * {@literal JsonArray}s of key/value {@literal JsonObject}s are deserialized to {@literal Map<?, ?>}.
+     */
+    private Map<?, ?> deserializeMap( ModuleDescriptor module, MapType mapType, JsonStructure json )
+    {
+        if( json.getValueType() == JsonValue.ValueType.OBJECT )
+        {
+            JsonObject object = (JsonObject) json;
+            return object.entrySet().stream()
+                         .map( entry -> new AbstractMap.SimpleImmutableEntry<>(
+                             entry.getKey(),
+                             doDeserialize( module, mapType.valueType(), entry.getValue() ) ) )
+                         .collect( toMapWithNullValues( LinkedHashMap::new ) );
+        }
+        if( json.getValueType() == JsonValue.ValueType.ARRAY )
+        {
+            JsonArray array = (JsonArray) json;
+            return array.stream()
+                        .map( JsonObject.class::cast )
+                        .map( entry -> new AbstractMap.SimpleImmutableEntry<>(
+                            doDeserialize( module, mapType.keyType(), entry.get( "key" ) ),
+                            doDeserialize( module, mapType.valueType(), entry.get( "value" ) )
+                        ) )
+                        .collect( toMapWithNullValues( LinkedHashMap::new ) );
+        }
+        throw new SerializationException( "Don't know how to deserialize " + mapType + " from " + json );
+    }
+
+    private Object deserializeValueComposite( ModuleDescriptor module, ValueCompositeType valueType, JsonObject json )
+    {
+        String typeInfoName = getTypeInfoPropertyName();
+        String typeInfo = json.getString( typeInfoName, null );
+        if( typeInfo != null )
+        {
+            ValueDescriptor descriptor = module.valueDescriptor( typeInfo );
+            if( descriptor == null )
+            {
+                throw new SerializationException(
+                    typeInfoName + ": " + typeInfo + " could not be resolved while deserializing " + json );
+            }
+            valueType = descriptor.valueType();
+        }
+        ValueBuilder builder = module.instance().newValueBuilderWithState(
+            valueType.primaryType(),
+            propertyFunction( module, json ),
+            associationFunction( module, json ),
+            manyAssociationFunction( module, json ),
+            namedAssociationFunction( module, json ) );
+        return builder.newInstance();
+    }
+
+    private Function<PropertyDescriptor, Object> propertyFunction( ModuleDescriptor module, JsonObject object )
+    {
+        return property ->
+        {
+            JsonValue jsonValue = object.get( property.qualifiedName().name() );
+            if( jsonValue != null )
+            {
+                Object value = doDeserialize( module, property.valueType(), jsonValue );
+                if( property.isImmutable() )
+                {
+                    if( value instanceof Set )
+                    {
+                        return unmodifiableSet( (Set<?>) value );
+                    }
+                    else if( value instanceof List )
+                    {
+                        return unmodifiableList( (List<?>) value );
+                    }
+                    else if( value instanceof Map )
+                    {
+                        return unmodifiableMap( (Map<?, ?>) value );
+                    }
+                }
+                return value;
+            }
+            return property.resolveInitialValue( module );
+        };
+    }
+
+    private Function<AssociationDescriptor, EntityReference> associationFunction( ModuleDescriptor module,
+                                                                                  JsonObject object )
+    {
+        return association -> doDeserialize( module, ValueType.ENTITY_REFERENCE,
+                                             object.get( association.qualifiedName().name() ) );
+    }
+
+    private Function<AssociationDescriptor, Stream<EntityReference>> manyAssociationFunction( ModuleDescriptor module,
+                                                                                              JsonObject object )
+    {
+        return association ->
+        {
+            List<EntityReference> list = doDeserialize( module, ENTITY_REF_LIST_VALUE_TYPE,
+                                                        object.get( association.qualifiedName().name() ) );
+            return list == null ? Stream.empty() : list.stream();
+        };
+    }
+
+    private Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssociationFunction(
+        ModuleDescriptor module, JsonObject object )
+    {
+        return association ->
+        {
+            Map<String, EntityReference> map = doDeserialize( module, ENTITY_REF_MAP_VALUE_TYPE,
+                                                              object.get( association.qualifiedName().name() ) );
+            return map == null ? Stream.empty() : map.entrySet().stream();
+        };
+    }
+
+    private Object deserializeBase64( String inputString )
+    {
+        byte[] bytes = inputString.getBytes( UTF_8 );
+        bytes = Base64.getDecoder().decode( bytes );
+        try( ObjectInputStream oin = new ObjectInputStream( new ByteArrayInputStream( bytes ) ) )
+        {
+            return oin.readObject();
+        }
+        catch( IOException | ClassNotFoundException ex )
+        {
+            throw new SerializationException( "Unable to deserialize Base64 serialized " + inputString, ex );
+        }
+    }
+
+    private String getTypeInfoPropertyName()
+    {
+        return JavaxJsonSettings.orDefault( descriptor.metaInfo( JavaxJsonSettings.class ) )
+                                .getTypeInfoPropertyName();
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerialization.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerialization.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerialization.java
new file mode 100644
index 0000000..2e034b0
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerialization.java
@@ -0,0 +1,26 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.serialization.javaxjson;
+
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.spi.serialization.JsonSerialization;
+
+@Mixins( { JavaxJsonSerializer.class, JavaxJsonDeserializer.class } )
+public interface JavaxJsonSerialization extends JsonSerialization
+{
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java
new file mode 100644
index 0000000..2b662ea
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java
@@ -0,0 +1,533 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.serialization.javaxjson;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.Period;
+import java.time.ZonedDateTime;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import javax.json.Json;
+import javax.json.JsonNumber;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.identity.Identity;
+import org.apache.polygene.api.identity.StringIdentity;
+import org.apache.polygene.api.injection.scope.This;
+import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.serialization.SerializationException;
+import org.apache.polygene.api.service.ServiceActivation;
+import org.apache.polygene.api.service.ServiceDescriptor;
+import org.apache.polygene.api.type.ValueType;
+
+// TODO Move into JavaxJsonSerialization
+// TODO Do the same on XML & MessagePack
+@Mixins( JavaxJsonSerializationService.Activation.class )
+public interface JavaxJsonSerializationService extends JavaxJsonSerialization, ServiceActivation
+{
+    class Activation implements ServiceActivation
+    {
+        @Uses
+        private ServiceDescriptor descriptor;
+
+        @This
+        private JavaxJsonAdapters adapters;
+
+        private boolean registrationDone = false;
+
+        @Override
+        public void activateService()
+        {
+            if( !registrationDone )
+            {
+                registerCustomAdapters();
+                registerBaseAdapters();
+                registrationDone = true;
+            }
+        }
+
+        @Override
+        public void passivateService() {}
+
+        private void registerCustomAdapters()
+        {
+            JavaxJsonSettings.orDefault( descriptor.metaInfo( JavaxJsonSettings.class ) )
+                             .getAdapters()
+                             .forEach( ( valueType, adapter ) -> adapters.registerAdapter( valueType, adapter ) );
+        }
+
+        private void registerBaseAdapters()
+        {
+            // Primitive Value types
+            adapters.registerAdapter( ValueType.STRING, new StringAdapter() );
+            adapters.registerAdapter( ValueType.CHARACTER, new CharacterAdapter() );
+            adapters.registerAdapter( ValueType.BOOLEAN, new BooleanAdapter() );
+            adapters.registerAdapter( ValueType.INTEGER, new IntegerAdapter() );
+            adapters.registerAdapter( ValueType.LONG, new LongAdapter() );
+            adapters.registerAdapter( ValueType.SHORT, new ShortAdapter() );
+            adapters.registerAdapter( ValueType.BYTE, new ByteAdapter() );
+            adapters.registerAdapter( ValueType.FLOAT, new FloatAdapter() );
+            adapters.registerAdapter( ValueType.DOUBLE, new DoubleAdapter() );
+
+            // Number types
+            adapters.registerAdapter( ValueType.BIG_DECIMAL, new BigDecimalAdapter() );
+            adapters.registerAdapter( ValueType.BIG_INTEGER, new BigIntegerAdapter() );
+
+            // Date types
+            adapters.registerAdapter( ValueType.INSTANT, new InstantAdapter() );
+            adapters.registerAdapter( ValueType.ZONED_DATE_TIME, new ZonedDateTimeAdapter() );
+            adapters.registerAdapter( ValueType.OFFSET_DATE_TIME, new OffsetDateTimeAdapter() );
+            adapters.registerAdapter( ValueType.LOCAL_DATE_TIME, new LocalDateTimeAdapter() );
+            adapters.registerAdapter( ValueType.LOCAL_DATE, new LocalDateAdapter() );
+            adapters.registerAdapter( ValueType.LOCAL_TIME, new LocalTimeAdapter() );
+            adapters.registerAdapter( ValueType.DURATION, new DurationAdapter() );
+            adapters.registerAdapter( ValueType.PERIOD, new PeriodAdapter() );
+
+            // Other supported types
+            adapters.registerAdapter( ValueType.IDENTITY, new IdentityAdapter() );
+            adapters.registerAdapter( ValueType.ENTITY_REFERENCE, new EntityReferenceAdapter() );
+        }
+
+        private static abstract class ToJsonStringAdapter<T> implements JavaxJsonAdapter<T>
+        {
+            @Override
+            public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+            {
+                return JavaxJson.toJsonString( object );
+            }
+        }
+
+        private static class StringAdapter extends ToJsonStringAdapter<String>
+        {
+            @Override
+            public Class<String> type() { return String.class; }
+
+            @Override
+            public String deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                return JavaxJson.asString( json );
+            }
+        }
+
+        private static class CharacterAdapter extends ToJsonStringAdapter<Character>
+        {
+            @Override
+            public Class<Character> type() { return Character.class; }
+
+            @Override
+            public Character deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                String string = JavaxJson.asString( json );
+                return string.isEmpty() ? null : string.charAt( 0 );
+            }
+        }
+
+        private static class BooleanAdapter implements JavaxJsonAdapter<Boolean>
+        {
+            @Override
+            public Class<Boolean> type() { return Boolean.class; }
+
+            @Override
+            public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+            {
+                return type().cast( object ) ? JsonValue.TRUE : JsonValue.FALSE;
+            }
+
+            @Override
+            public Boolean deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                switch( json.getValueType() )
+                {
+                    case TRUE:
+                        return true;
+                    case FALSE:
+                        return false;
+                    case NULL:
+                        return null;
+                    case NUMBER:
+                        return ( (JsonNumber) json ).doubleValue() > 0;
+                    case STRING:
+                        return Boolean.valueOf( ( (JsonString) json ).getString() );
+                    default:
+                        throw new SerializationException( "Don't know how to deserialize Boolean from " + json );
+                }
+            }
+        }
+
+        private static class IntegerAdapter implements JavaxJsonAdapter<Integer>
+        {
+            @Override
+            public Class<Integer> type() { return Integer.class; }
+
+            @Override
+            public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+            {
+                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
+                           .getJsonNumber( "value" );
+            }
+
+            @Override
+            public Integer deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                switch( json.getValueType() )
+                {
+                    case NULL:
+                        return null;
+                    case NUMBER:
+                        return ( (JsonNumber) json ).intValueExact();
+                    case STRING:
+                        String string = ( (JsonString) json ).getString();
+                        return string.isEmpty() ? 0 : Integer.parseInt( string );
+                    default:
+                        throw new SerializationException( "Don't know how to deserialize Integer from " + json );
+                }
+            }
+        }
+
+        private static class LongAdapter implements JavaxJsonAdapter<Long>
+        {
+            @Override
+            public Class<Long> type() { return Long.class; }
+
+            @Override
+            public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+            {
+                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build().getJsonNumber(
+                    "value" );
+            }
+
+            @Override
+            public Long deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                switch( json.getValueType() )
+                {
+                    case NULL:
+                        return null;
+                    case NUMBER:
+                        return ( (JsonNumber) json ).longValueExact();
+                    case STRING:
+                        String string = ( (JsonString) json ).getString();
+                        return string.isEmpty() ? 0L : Long.parseLong( string );
+                    default:
+                        throw new SerializationException( "Don't know how to deserialize Long from " + json );
+                }
+            }
+        }
+
+        private static class ShortAdapter implements JavaxJsonAdapter<Short>
+        {
+            @Override
+            public Class<Short> type() { return Short.class; }
+
+            @Override
+            public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+            {
+                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
+                           .getJsonNumber( "value" );
+            }
+
+            @Override
+            public Short deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                switch( json.getValueType() )
+                {
+                    case NULL:
+                        return null;
+                    case NUMBER:
+                        return (short) ( (JsonNumber) json ).intValueExact();
+                    case STRING:
+                        String string = ( (JsonString) json ).getString();
+                        return string.isEmpty() ? 0 : Short.parseShort( string );
+                    default:
+                        throw new SerializationException( "Don't know how to deserialize Short from " + json );
+                }
+            }
+        }
+
+        private static class ByteAdapter implements JavaxJsonAdapter<Byte>
+        {
+            @Override
+            public Class<Byte> type() { return Byte.class; }
+
+            @Override
+            public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+            {
+                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
+                           .getJsonNumber( "value" );
+            }
+
+            @Override
+            public Byte deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                switch( json.getValueType() )
+                {
+                    case NULL:
+                        return null;
+                    case NUMBER:
+                        return (byte) ( (JsonNumber) json ).intValueExact();
+                    case STRING:
+                        String string = ( (JsonString) json ).getString();
+                        return string.isEmpty() ? 0 : Byte.parseByte( string );
+                    default:
+                        throw new SerializationException( "Don't know how to deserialize Byte from " + json );
+                }
+            }
+        }
+
+        private static class FloatAdapter implements JavaxJsonAdapter<Float>
+        {
+            @Override
+            public Class<Float> type() { return Float.class; }
+
+            @Override
+            public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+            {
+                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
+                           .getJsonNumber( "value" );
+            }
+
+            @Override
+            public Float deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                switch( json.getValueType() )
+                {
+                    case NULL:
+                        return null;
+                    case NUMBER:
+                        return (float) ( (JsonNumber) json ).doubleValue();
+                    case STRING:
+                        String string = ( (JsonString) json ).getString();
+                        return string.isEmpty() ? 0F : Float.parseFloat( string );
+                    default:
+                        throw new SerializationException( "Don't know how to deserialize Float from " + json );
+                }
+            }
+        }
+
+        private static class DoubleAdapter implements JavaxJsonAdapter<Double>
+        {
+            @Override
+            public Class<Double> type() { return Double.class; }
+
+            @Override
+            public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+            {
+                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
+                           .getJsonNumber( "value" );
+            }
+
+            @Override
+            public Double deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                switch( json.getValueType() )
+                {
+                    case NULL:
+                        return null;
+                    case NUMBER:
+                        return ( (JsonNumber) json ).doubleValue();
+                    case STRING:
+                        String string = ( (JsonString) json ).getString();
+                        return string.isEmpty() ? 0D : Double.parseDouble( string );
+                    default:
+                        throw new SerializationException( "Don't know how to deserialize Double from " + json );
+                }
+            }
+        }
+
+        private static class BigDecimalAdapter extends ToJsonStringAdapter<BigDecimal>
+        {
+            @Override
+            public Class<BigDecimal> type() { return BigDecimal.class; }
+
+            @Override
+            public BigDecimal deserialize( JsonValue json,
+                                           BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                switch( json.getValueType() )
+                {
+                    case NULL:
+                        return null;
+                    case NUMBER:
+                        return new BigDecimal( json.toString() );
+                    case STRING:
+                        return new BigDecimal( ( (JsonString) json ).getString() );
+                    default:
+                        throw new SerializationException(
+                            "Don't know how to deserialize BigDecimal from " + json );
+                }
+            }
+        }
+
+        private static class BigIntegerAdapter extends ToJsonStringAdapter<BigInteger>
+        {
+            @Override
+            public Class<BigInteger> type() { return BigInteger.class; }
+
+            @Override
+            public BigInteger deserialize( JsonValue json,
+                                           BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                switch( json.getValueType() )
+                {
+                    case NULL:
+                        return null;
+                    case NUMBER:
+                        return new BigInteger( json.toString() );
+                    case STRING:
+                        return new BigInteger( ( (JsonString) json ).getString() );
+                    default:
+                        throw new SerializationException(
+                            "Don't know how to deserialize BigInteger from " + json );
+                }
+            }
+        }
+
+        private static class PeriodAdapter extends ToJsonStringAdapter<Period>
+        {
+            @Override
+            public Class<Period> type() { return Period.class; }
+
+            @Override
+            public Period deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                return Period.parse( JavaxJson.asString( json ) );
+            }
+        }
+
+        private static class DurationAdapter extends ToJsonStringAdapter<Duration>
+        {
+            @Override
+            public Class<Duration> type() { return Duration.class; }
+
+            @Override
+            public Duration deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                return Duration.parse( JavaxJson.asString( json ) );
+            }
+        }
+
+        private static class LocalTimeAdapter extends ToJsonStringAdapter<LocalTime>
+        {
+            @Override
+            public Class<LocalTime> type() { return LocalTime.class; }
+
+            @Override
+            public LocalTime deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                return LocalTime.parse( JavaxJson.asString( json ) );
+            }
+        }
+
+        private static class LocalDateAdapter extends ToJsonStringAdapter<LocalDate>
+        {
+            @Override
+            public Class<LocalDate> type() { return LocalDate.class; }
+
+            @Override
+            public LocalDate deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                return LocalDate.parse( JavaxJson.asString( json ) );
+            }
+        }
+
+        private static class LocalDateTimeAdapter extends ToJsonStringAdapter<LocalDateTime>
+        {
+            @Override
+            public Class<LocalDateTime> type() { return LocalDateTime.class; }
+
+            @Override
+            public LocalDateTime deserialize( JsonValue json,
+                                              BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                return LocalDateTime.parse( JavaxJson.asString( json ) );
+            }
+        }
+
+        private static class OffsetDateTimeAdapter extends ToJsonStringAdapter<OffsetDateTime>
+        {
+            @Override
+            public Class<OffsetDateTime> type() { return OffsetDateTime.class; }
+
+            @Override
+            public OffsetDateTime deserialize( JsonValue json,
+                                               BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                return OffsetDateTime.parse( JavaxJson.asString( json ) );
+            }
+        }
+
+        private static class ZonedDateTimeAdapter extends ToJsonStringAdapter<ZonedDateTime>
+        {
+            @Override
+            public Class<ZonedDateTime> type() { return ZonedDateTime.class; }
+
+            @Override
+            public ZonedDateTime deserialize( JsonValue json,
+                                              BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                return ZonedDateTime.parse( JavaxJson.asString( json ) );
+            }
+        }
+
+        private static class InstantAdapter extends ToJsonStringAdapter<Instant>
+        {
+            @Override
+            public Class<Instant> type() { return Instant.class; }
+
+            @Override
+            public Instant deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                return Instant.parse( JavaxJson.asString( json ) );
+            }
+        }
+
+        private static class IdentityAdapter extends ToJsonStringAdapter<Identity>
+        {
+            @Override
+            public Class<Identity> type() { return Identity.class; }
+
+            @Override
+            public Identity deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                return StringIdentity.fromString( JavaxJson.asString( json ) );
+            }
+        }
+
+        private static class EntityReferenceAdapter extends ToJsonStringAdapter<EntityReference>
+        {
+            @Override
+            public Class<EntityReference> type() { return EntityReference.class; }
+
+            @Override
+            public EntityReference deserialize( JsonValue json,
+                                                BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+            {
+                return EntityReference.parseEntityReference( JavaxJson.asString( json ) );
+            }
+        }
+    }
+}