Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EclipseLink/DesignDocs/384399"

(GUI)
m (Internal Classes)
 
(170 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Design Specification: MOXy Footprint Reduction> =
+
= Design Specification: MOXy Footprint Reduction =
  
 
[http://bugs.eclipse.org/384399 ER 384399]
 
[http://bugs.eclipse.org/384399 ER 384399]
Line 12: Line 12:
 
| 2012/07/05
 
| 2012/07/05
 
| Blaise Doughan
 
| Blaise Doughan
| Work In Progress
+
| Initial draft
 +
|-
 +
| 2012/08/20
 +
| Blaise Doughan
 +
| Pre-review Draft
 +
|-
 +
| 2012/09/17
 +
| Blaise Doughan
 +
| Updated document to reflect new strategy for reducing MOXy's install footprint.
 +
|-
 +
| 2012/09/21
 +
| Blaise Doughan
 +
| Updated document based on feed back from design review on 2012/09/19
 +
|-
 +
| 2012/09/24
 +
| Blaise Doughan
 +
| Review Version
 +
|-
 +
| 2012/11/05
 +
| Blaise Doughan
 +
| Progress Update
 
|-
 
|-
|
 
 
|
 
|
 
|
 
|
Line 21: Line 40:
 
== Project overview ==
 
== Project overview ==
  
Overview of the project/feature.  Why is it desired, what are its goals.
+
=== Problem ===
  
Goals:
+
The install footprint is currently preventing MOXy from being bundled with other software and used on mobile platforms. 
* goal 1
+
 
* goal 2
+
'''XML Binding Install Footprint (EclipseLink 2.4)'''
 +
 
 +
{|{{BMTableStyle}}
 +
|-{{BMTHStyle}}
 +
! Bundle
 +
! Size
 +
|-
 +
| org.eclipse.persistence.moxy_2.4.0.v20120608-r11652.jar
 +
| 455 KB
 +
|-
 +
| org.eclipse.persistence.asm_3.3.1.v201206041142.jar
 +
| 271 KB
 +
|-
 +
| org.eclipse.persistence.core_2.4.0.v20120608-r11652.jar
 +
| 4711 KB
 +
|-
 +
|
 +
| 5437 KB
 +
|}
 +
 
 +
'''JSON Binding Install Footprint (EclipseLink 2.4)'''
 +
 
 +
{|{{BMTableStyle}}
 +
|-{{BMTHStyle}}
 +
! Bundle
 +
! Size
 +
|-
 +
| org.eclipse.persistence.moxy_2.4.0.v20120608-r11652.jar
 +
| 455 KB
 +
|-
 +
| org.eclipse.persistence.asm_3.3.1.v201206041142.jar
 +
| 271 KB
 +
|-
 +
| org.eclipse.persistence.core_2.4.0.v20120608-r11652.jar
 +
| 4711 KB
 +
|-
 +
| org.eclipse.persistence.antlr_3.2.0.v201206041011.jar
 +
| 190 KB
 +
|-
 +
|
 +
| 5627 KB
 +
|}
 +
 
 +
=== Primary Goals ===
 +
 
 +
Reduce the size of X so that is no more that 600 KB.
 +
 
 +
{|{{BMTableStyle}}
 +
|-{{BMTHStyle}}
 +
! Bundle
 +
! Size
 +
|-
 +
| org.eclipse.persistence.moxy_2.4.0.v20120608-r11652.jar
 +
| 455 KB
 +
|-
 +
| org.eclipse.persistence.asm_3.3.1.v201206041142.jar
 +
| 271 KB
 +
|-
 +
| org.eclipse.persistence.oxm_2.4.0.v20120608-r11652.jar
 +
| X KB
 +
|-
 +
| org.eclipse.persistence.antlr_3.2.0.v201206041011.jar
 +
| 190 KB
 +
|-
 +
|
 +
| (726 + X) KB (XML) / (916 + X) KB (JSON)
 +
|}
 +
 
 +
=== Secondary Goals ===
 +
 
 +
==== Memory Improvement ====
 +
 
 +
Many of the current "core" classes contains information that is only required for object-relational mapping.  This type of metadata needlessly increases the amount of memory MOXy requires to run.  This refactor will reduce the amount of memory MOXy requires to run.
  
 
== Concepts ==
 
== Concepts ==
  
Present any concepts relevant to the feature.
+
=== Package Splitting ===
 +
 
 +
This is when classes from the same package are distributed among different bundles.  Modularity frameworks discourage splitting packages and therefore is something that we can not do.
 +
 
 +
 
 +
=== Backwards Compatibility ===
 +
 
 +
Support applications written/compiled against previous versions of EclipseLink.  Failing to be backwards compatible will have a negative impact on our user base.  Anything less than binary compatibility will affect applications that include EclipseLink.
 +
 
 +
==== Binary Compatible ====
 +
 
 +
Applications compiled against EclipseLink before the footprint reduction will continue to work against EclipseLink after the footprint reduction. 
 +
 
 +
==== Source Code Compatible ====
 +
 
 +
Applications compiled against EclipseLink before the footprint reduction will not continue to work against EclipseLink after the footprint reduction.  The user won't need to modify their source code, but they will need to recompile it against the new version of EclipseLink.
 +
 
 +
==== Incompatible ====
 +
 
 +
The user would need to make changes to their code to work with the new version of EclipseLink.  We could leverage the "package renamer" tool to make it easier for users to migrate their code to the new APIs.
 +
 
 +
 
 +
=== Generics & Parameterized Types ===
 +
 
 +
This design makes use of generics, below is an example if you are not familiar with the mechanism in Java.
 +
 
 +
<source lang="java">
 +
package demo;
 +
 +
import java.lang.reflect.Method;
 +
 +
public class Demo {
 +
private static String METHOD_NAME = "sample";
 +
private static Class<?>[] PARAMETER_TYPES = new Class[] {String.class};
 +
 +
public static void main(String[] args) throws Exception {
 +
// Use Method - Test Method Can Be Called
 +
Integer a = new Foo().sample("A"); // YES
 +
Integer b = new Bar().sample("B"); // YES
 +
Integer c = new Baz().sample("C"); // YES
 +
 +
// Reflection - Test Method Accessed Via Reflection
 +
hasMethod(Foo.class, METHOD_NAME, PARAMETER_TYPES); // YES
 +
hasMethod(Bar.class, METHOD_NAME, PARAMETER_TYPES); // NO
 +
hasMethod(Baz.class, METHOD_NAME, PARAMETER_TYPES); // YES
 +
}
 +
 +
private static void hasMethod(Class<?> clazz, String methodName, Class<?>[] parameterTypes) {
 +
try {
 +
Method method = clazz.getMethod(methodName, parameterTypes);
 +
System.out.println(method);
 +
} catch(NoSuchMethodException e) {
 +
e.printStackTrace();
 +
}
 +
}
 +
 +
// Regular Java Class
 +
static class Foo {
 +
public Integer sample(String string) {
 +
return null;
 +
}
 +
}
 +
 +
// Parameterized Type
 +
static abstract class AbstractBar<RETURN, PARAMETER> {
 +
private RETURN value;
 +
 +
public RETURN sample(PARAMETER parameter) {
 +
return value;
 +
}
 +
}
 +
 +
// Subclass of Parameterized type
 +
static class Bar extends AbstractBar<Integer, String>{
 +
}
 +
 +
// Subclass of Parameterized type that overrides method from super class
 +
static class Baz extends AbstractBar<Integer, String> {
 +
@Override
 +
public Integer sample(String parameter) {
 +
return super.sample(parameter);
 +
}
 +
}
 +
}
 +
</source>
 +
 
 +
 
 +
=== MOXy's DOM & SAX Platforms ===
 +
 
 +
MOXy contains two object-to-XML implementations: DOMPlatform and SAXPlatform.  DOMPlatform was the first implementation and closely mirrors the mechanisms used by EclipseLink's object-to-relational mapping.  SAXPlatform was introduced second as a performance improvement and now has almost completely replaced all usages of DOMPlatform.
  
 
== Requirements ==
 
== Requirements ==
  
The following sections will expand the goals of this project into more concrete requirements.
+
# Existing classes must remain '''[http://wiki.eclipse.org/EclipseLink/DesignDocs/384399#Binary_Compatible binary compatible]'''.  This means that applications compiled against a previous version of EclipseLink must continue to run against the version of EclipseLink that implements the footprint reduction.  Breaking backwards (binary) compatibility would require us to due a whole number version increment (i.e. 2.4.-> 3.0 and not 2.4 -> 2.5).
  
== Design Constraints ==
 
  
== Design / Functionality ==
 
  
== Testing ==
+
== Design / Functionality  ==
 +
 
 +
The following covers how [http://wiki.eclipse.org/EclipseLink/DesignDocs/384399#Option_.233_-_Fork_OXM.2FJAXB_Layers approach #3] could be accomplished.
 +
 
 +
=== High Level  ===
 +
 
 +
MOXy contains two mechanisms for converting objects to/from XML:  DOMPlatform and SAXPlatform.  DOMPlatform has strong roots in ORM processing (supports queries, change sets, etc) and is leveraged by EclipseLink EIS.  SAXPlatform was introduced to optimize the binding use case as part of the JAXB implementation.  The SAXPlatform shares much less logic with the ORM layer than the DOMPlatform does, but shares all the same dependencies.  The goal of this feature is to extract only the code necessary to make the SAXPlatform work in order to support the JAXB use case.
 +
 
 +
*Interfaces and abstract classes will be created to represent functionality common to core OXM and ORM behaviour.
 +
*Private OXM classes will be modified to interact with the new common interfaces/classes.
 +
*Existing core classes will implement/extend the new common interfaces/classes.
 +
*New MOXy classes will be created that implement the new common interfaces/classes.
 +
 
 +
=== Bundle Changes ===
 +
 
 +
#Introduce a new org.eclipse.persistence.bind bundle to contain common classes and interfaces and the light-weight OXM implementation.
 +
#Modify the core bundle to depend on the new bind bundle.
 +
#Move MOXy specify items from core into MOXy bundle (this is different from the new bind bundle)
 +
#Move old OXM code into separate bundle for backwards compatibility (once core bundle no longer depends upon old OXM classes)
 +
 
 +
=== New Core Abstractions ===
 +
 
 +
{|
 +
|-
 +
! Current ([http://yuml.me/edit/e430c5aa edit])
 +
!
 +
! Proposed ([http://yuml.me/edit/5ac76d24 edit])
 +
|-
 +
| [[Image:DesignDoc384399-Before.jpg]]
 +
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 +
| [[Image:DesignDoc384399-Proposed.jpg]]
 +
|}
 +
 
 +
The following are core classes that are required by MOXy.  These classes currently have dependencies on other ORM specific classes.  As part of this feature new super classes will be created for each of these classes to contain the shared behaviour and state.  The abstractions will maintain the same package structure under:
 +
 
 +
*org.eclipse.persistence.core
 +
*org.eclipse.persistence.internal.core
 +
 
 +
==== Public Classes ====
 +
 
 +
This refactoring will affect the following public classes.  Binary compatibility will be maintained as a result of this refactoring.
 +
 
 +
#org.eclipse.persistence.descriptors.ClassDescriptor
 +
##getEventManager
 +
##getInheritancePolicy
 +
##getInstantiationPolicy
 +
##getJavaClass
 +
##getObjectBuilder
 +
##getPrimaryKeyFieldNames
 +
##getPrimaryKeyFields
 +
##getTypedField
 +
##hasEventManager
 +
##hasInheritance
 +
##setEventManager
 +
##setInheritancePolicy
 +
##setInstantiationPolicy
 +
##setJavaClass
 +
##setObjectBuilder
 +
##setPrimaryKeyFieldNames
 +
##setPimraryKeyFields
 +
#org.eclipse.persistence.descriptors.DescriptorEvent
 +
##setEventCode
 +
##setRecord
 +
##setSession
 +
#org.eclipse.persistence.descriptors.DescriptorEventManager
 +
##executeEvent
 +
##hasAnyEventListeners
 +
#org.eclipse.persistence.descriptors.InheritancePolicy
 +
##classFromRow
 +
##getAllChildDescriptors
 +
##getClassIndicatorField
 +
##getClassIndicatorMappings
 +
##getDescriptor
 +
##setClassIndicatorField
 +
##setClassIndicatorMapping
 +
##setDescriptor
 +
#org.eclipse.persistence.mappings.DatabaseMapping
 +
##getAttributeAccessor
 +
##getAttributeClassification
 +
##getAttributeValueFromObject
 +
##getContainerPolicy
 +
##getDescriptor
 +
##getField
 +
##getFields
 +
##getReferenceDescriptor
 +
##isAbstractCompositeCollectionMapping()
 +
##isAbstractCompositeDirectCollectionMapping()
 +
##isDirectToFieldMapping
 +
##isReadOnly
 +
##isWriteOnly
 +
##setAttributeAccessor
 +
##setAttributeValueInObject
 +
##setDescriptor
 +
##setFields
 +
##valueFromObject
 +
#org.eclipse.persistence.mappings.converters.Converter
 +
##convertDataValueToObjectValue
 +
##convertObjectValueToDataValue
 +
##initialize
 +
#org.eclipse.persistence.sessions.Project (TBD)
 +
##TBD
 +
#org.eclipse.persistence.sessions.Session (2 methods)
 +
##getDescriptor
 +
##getProperty
 +
 
 +
==== Internal Classes ====
 +
 
 +
This refactoring will affect the following internal classes.  Even though these classes are technically internal they are probably leveraged by some of our users so binary compatibility will be maintained for these classes as well.
 +
 
 +
#org.eclipse.persistence.internal.databaseaccess.Platform (1 method)
 +
##getConversionManager
 +
#org.eclipse.persistence.internal.descriptors.InstantiationPolicy (1 method)
 +
##buildNewInstance
 +
#org.eclipse.persistence.internal.descriptors.ObjectBuilder (2 methods)
 +
##createRecord
 +
##extractPrimaryKeyFromObject
 +
#org.eclipse.persistence.internal.helper.ClassConstants (5 constants)
 +
##ABYTE (static constant)
 +
##APBYTE (static constant)
 +
##APCHAR (static constant)
 +
##OBJECT (static constant)
 +
##STRING (static constant)
 +
#org.eclipse.persistence.internal.helper.ConversionManager (1 method)
 +
##convertObject
 +
#org.eclipse.persistence.internal.helper.DatabaseField (4 methods)
 +
##getName
 +
##setName
 +
##getType
 +
##setType
 +
#org.eclipse.persistence.internal.helper.Helper (1 static method)
 +
##cr (static)
 +
#org.eclipse.persistence.internal.sessions.AbstractRecord (0 methods)
 +
#org.eclipse.persistence.internal.sessions.AbstractSession (3 methods)
 +
##getDatasourcePlatform
 +
##getDescriptor
 +
##getDescriptors
 +
 
 +
=== Areas Where We Need to Duplicate Code ===
 +
 
 +
Where there is an inheritance hierarchy a set of interfaces will be introduced in the core layer to represent the APIs required by both MOXy and ORM.  The existing ORM classes will be modified to implement these interfaces and new implementations will be added in the MOXy layer.
 +
 
 +
*org.eclipse.persistence.internal.queries.ContainerPolicy
 +
**org.eclipse.persistence.internal.queries.InterfaceContainerPolicy
 +
***org.eclipse.persistence.internal.queries.CollectionContainerPolicy
 +
***org.eclipse.persistence.internal.queries.MapContainerPolicy
 +
*org.eclipse.persistence.mappings.AttributeAccessor
 +
**org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor
 +
**org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor
 +
**Many more
 +
 
 +
=== Public OXM Classes ===
 +
 
 +
*A mirror of the classes in the org.eclipse.persistence.oxm package will be created under the org.eclipse.persistence.bind package.  XML specific classes will me put under a org.eclipse.persistence.bind.xml package.
 +
*The classes under the new org.eclipse.persistence.bind package will be refactored to use the APIs in the new bind and core packages.
 +
*The classes under the old org.eclipse.persistence.oxm package will be refactored to extend from or delegate to the new bind and core classes.
 +
 
 +
=== Internal OXM Classes (SAX Platform Related) ===
 +
 
 +
The following will be done to the classes in the internal.oxm package that are related to the SAX platform:
 +
 
 +
*The will be updated to leverage the refactored classes from the previous steps.
 +
*The classes related to binding in general will be moved under the org.eclipse.persistence.internal.bind package.
 +
*The classes related to XML binding specifically will be moved under the org.eclipse.persistence.internal.bind.xml package.
 +
*The classes related to JSON binding specifically will be moved under the org.eclipse.persistence.internal.bind.json package.
 +
 
 +
== Development Plan  ==
 +
 
 +
Below is what the development plan would look like if we decide to maintain binary backwards compatibility of the native OXM APIs (see [http://wiki.eclipse.org/EclipseLink/DesignDocs/384399#Open_Issues Open Issue #2]).
 +
 
 +
=== Phase #1 - Introduce Core Abstraction Classes ===
 +
 
 +
Introduce the new core abstraction classes and change the existing core bundle to extend them.
 +
 
 +
=== Phase #2 - Introduce Core Interface Classes ===
 +
 
 +
Introduce the new core interfaces and change the corresponding core classes to implement them.
 +
 
 +
=== Phase #3 - Refactor the internal.oxm classes to depend on the classes created in Phases #1 and #2. ===
 +
 
 +
At this point the internal.oxm classes that are related to the SAX platform should only depend on classes in the oxm, internal.oxm, core, or internal.core packages.
 +
 
 +
=== Phase #4 - Pull ''internal.oxm'' Classes and Common Classes/Interfaces Into a New ''org.eclipse.persistence.bind'' Bundle ===
 +
 
 +
The ''internal.oxm'' classes and the new common classes/interfaces will form the basis of a new ''org.eclipse.persistence.bind'' bundle.  The core bundle will be dependent on this new bundle.  During this move the XML prefix on class names will be dropped, and the internal.oxm package will be renamed internal.bind.  This is to reflect that MOXy now supports more than just object-to-XML mapping (MOXy also supports object-to-JSON mapping).
 +
 
 +
=== Phase #5 - Implement Light Weight OXM Version of Core Classes/Interfaces ===
 +
 
 +
A lightweight version of the core classes/interfaces will be implemented in the ''org.eclipse.persistence.bind'' package.  Where possible the corresponding implementations in the ''org.eclipse.persistence.oxm'' package will be updated to extend their counterparts in the bind bundle so that there is as little code duplication as possible.
 +
 
 +
=== Phase #6 - Refactor OXM Classes to Extend From or Delegate To Bind Classes ===
 +
 
 +
=== Phase #7 - Update MOXy JAXB to Use ''org.eclipse.persistence.bind'' Bundle ===
 +
 
 +
Switch MOXy JAXB to use the bind bundle. 
 +
 
 +
=== Phase #8 (Optional) - Update SDO to Use ''org.eclipse.persistence.bind'' Bundle ===
 +
 
 +
Switch SDO to use the bind bundle.  We may or may not want to introduce a binary incompatibility into the SDO implementation by making this change.
 +
 
 +
=== Phase #9 (Optional) - Update Core to Use ''org.eclipse.persistence.bind'' Bundle ===
 +
 
 +
Switch core to use the bind bundle.
 +
 
 +
=== Phase #10 (Optional) - Move org.eclipse.persistence.oxm Classes into an oxm Bundle ===
 +
 
 +
Once the core bundle is no longer dependent upon the oxm classes they could be moved into there own bundle.  This would reduce the footprint of the core bundle.  The oxm classes would still be available for anyone that required them for backwards compatibility reasons.
 +
 
 +
== Testing ==
 +
 
 +
=== Binary Compatible Testing ===
 +
 
 +
Testing would be required to ensure that binary compatibility is kept, for the areas we plan on maintaining binary compatibility.
  
 
== API ==
 
== API ==
  
== GUI ==
+
=== Core Packages ===
  
N/A
+
The common core classes will be under the following packages.  The final package structure will be reviewed once all the abstractions are known.
  
== Config files ==
+
*org.eclipse.persistence.core
 +
*org.eclipse.persistence.internal.core
  
N/A
+
=== Proposed Class Structure ===
 +
 
 +
'''New Abstractions (i.e. Descriptor)'''
 +
 
 +
A set of classes/interfaces will be created to represent the core functionality that is common to both object-to-XML and object-to-relational mapping.  Type variables will be leveraged so that the OXM and ORM implementations can be further specialized.
 +
 
 +
<source lang="java">
 +
package org.eclipse.persistence.internal.core;
 +
 
 +
public abstract class Descriptor<
 +
    OBJECT_BUILDER extends ObjectBuilder,
 +
    INHERITANCE_POLICY extends InheritancePolicy,
 +
    INSTANTIATION_POLICY extends InstantiationPolicy> {
 +
 
 +
    OBJECT_BUILDER getObjectBuilder();
 +
   
 +
    INHERITANCE_POLICY getInheritancePolicy();
 +
   
 +
    INSTANTIATION_POLICY getInstantiationPolicy();
 +
 
 +
}
 +
</source>
 +
 
 +
'''New OXM Classes'''
 +
 
 +
The new light weight MOXy will provide a new implementation of these core classes/interfaces (the class names below are for demonstration purposes only).  The existing core OXM classes will continue to work (see below).
 +
 
 +
<source lang="java">
 +
public class SmallXMLDescriptor extends Descriptor<SmallObjectBuilder, SmallInheritancePolicy, SmallInstantiationPolicy>, Cloneable, Serializable {
 +
 +
</source>
 +
 
 +
'''Existing Core Classes (i.e. ClassDescriptor)'''
 +
 
 +
The existing core classes will be modified to extends/implement these classes/interfaces supplying the appropriate type variables.  Everything else about the core classes will stay the same ensuring backwards compatibility.
 +
 
 +
<source lang="java">
 +
public class ClassDescriptor extends Descriptor<ObjectBuilder, InheritancePolicy, InstantiationPolicy>, Cloneable, Serializable {
 +
 +
</source>
  
 
== Documentation ==
 
== Documentation ==
  
== Open Issues ==
+
The following items will need to be documented:
 +
* What the binary incompatibilities are (if any).
  
This section lists the open issues that are still pending that must be decided prior to fully implementing this project's requirements.
+
== Open Issues  ==
 +
 
 +
This section lists the open issues that are still pending that must be decided prior to fully implementing this project's requirements.  
  
 
{|{{BMTableStyle}}
 
{|{{BMTableStyle}}
 
|-{{BMTHStyle}}
 
|-{{BMTHStyle}}
! Issue #
+
! Issue #  
! Owner
+
! Owner  
 
! Description / Notes
 
! Description / Notes
|-  
+
|-
|
+
| 1
 +
| Doug/Peter
 +
| Does the implementation of this feature require us to bump the version number to 3.0?
 +
|-
 +
| 2
 +
| Doug/Peter/Blaise
 +
| Do we need to maintain binary compatibility of the native OXM APIs?
 +
|-
 
|
 
|
 
|
 
|
Line 85: Line 524:
 
== Future Considerations ==
 
== Future Considerations ==
  
During the research for this project the following items were identified as out of scope but are captured here as potential future enhancements. If agreed upon during the review process these should be logged in the bug system.
+
=== Remove Need for ASM Bundle ===
 +
 
 +
There are a few areas where MOXy makes use of the ASM bundle to generate bytecodes. Some feature work could be done to eliminate the need to generate these bytecodes and the ASM dependency could be dropped removing it from the install footprint.
 +
 
 +
=== Remove Need for ANTLR Bundle ===
 +
 
 +
Currently the ANTLR bundle is required to parse JSON documents.  Once a standard JSON parser is available (see [http://jcp.org/en/jsr/detail?id=353]), we can remove dependency on ANTLR from MOXy.
 +
 
 +
=== Move ORM Specific Packages to JPA Bundle ===
 +
 
 +
Using the [http://www.dependency-analyzer.org/ Class Dependency Analyzer (CDA)] tool I was able to determine that the following packages could be removed from the core bundle without affecting MOXy.  Since we [http://wiki.eclipse.org/EclipseLink/DesignDocs/384399#Package_Splitting cannot split packages] only whole packages can be moved.  The classes in these packages represent approximately '''170 KB''' of the core bundle.
 +
 
 +
*org/eclipse/persistence/expressions/spatial
 +
*org/eclipse/persistence/internal/jpa/jpql
 +
*org/eclipse/persistence/platform/server/glassfish
 +
*org/eclipse/persistence/platform/server/jboss
 +
*org/eclipse/persistence/platform/server/oc4j
 +
*org/eclipse/persistence/platform/server/sap
 +
*org/eclipse/persistence/platform/server/sunas
 +
*org/eclipse/persistence/platform/server/was
 +
*org/eclipse/persistence/platform/server/wls
 +
*org/eclipse/persistence/services/glassfish
 +
*org/eclipse/persistence/services/jboss
 +
*org/eclipse/persistence/services/weblogic
 +
*org/eclipse/persistence/tools/file
 +
*org/eclipse/persistence/transaction
 +
*org/eclipse/persistence/transaction/glassfish
 +
*org/eclipse/persistence/transaction/jboss
 +
*org/eclipse/persistence/transaction/jotm
 +
*org/eclipse/persistence/transaction/oc4j
 +
*org/eclipse/persistence/transaction/sap
 +
*org/eclipse/persistence/transaction/sunas
 +
*org/eclipse/persistence/transaction/was
 +
*org/eclipse/persistence/transaction/wls
 +
 
 +
'''Enhancement Request (Contains Patch)'''
 +
 
 +
*http://bugs.eclipse.org/390116
 +
 
 +
'''Footprint Reduction'''
 +
 
 +
Approximately 170 KB
 +
 
 +
=== Project Jigsaw ===
 +
 
 +
Is a standard module system being designed for the Java SE platform.  It is being applied to the JDK itself.  While this feature is not dependent on Jigsaw, care will be taken as to what modules we will need to depend on.
 +
 
 +
* [http://openjdk.java.net/projects/jigsaw/ http://openjdk.java.net/projects/jigsaw/]

Latest revision as of 17:02, 9 November 2012

Contents

Design Specification: MOXy Footprint Reduction

ER 384399

Document History

Date Author Version Description & Notes
2012/07/05 Blaise Doughan Initial draft
2012/08/20 Blaise Doughan Pre-review Draft
2012/09/17 Blaise Doughan Updated document to reflect new strategy for reducing MOXy's install footprint.
2012/09/21 Blaise Doughan Updated document based on feed back from design review on 2012/09/19
2012/09/24 Blaise Doughan Review Version
2012/11/05 Blaise Doughan Progress Update

Project overview

Problem

The install footprint is currently preventing MOXy from being bundled with other software and used on mobile platforms.

XML Binding Install Footprint (EclipseLink 2.4)

Bundle Size
org.eclipse.persistence.moxy_2.4.0.v20120608-r11652.jar 455 KB
org.eclipse.persistence.asm_3.3.1.v201206041142.jar 271 KB
org.eclipse.persistence.core_2.4.0.v20120608-r11652.jar 4711 KB
5437 KB

JSON Binding Install Footprint (EclipseLink 2.4)

Bundle Size
org.eclipse.persistence.moxy_2.4.0.v20120608-r11652.jar 455 KB
org.eclipse.persistence.asm_3.3.1.v201206041142.jar 271 KB
org.eclipse.persistence.core_2.4.0.v20120608-r11652.jar 4711 KB
org.eclipse.persistence.antlr_3.2.0.v201206041011.jar 190 KB
5627 KB

Primary Goals

Reduce the size of X so that is no more that 600 KB.

Bundle Size
org.eclipse.persistence.moxy_2.4.0.v20120608-r11652.jar 455 KB
org.eclipse.persistence.asm_3.3.1.v201206041142.jar 271 KB
org.eclipse.persistence.oxm_2.4.0.v20120608-r11652.jar X KB
org.eclipse.persistence.antlr_3.2.0.v201206041011.jar 190 KB
(726 + X) KB (XML) / (916 + X) KB (JSON)

Secondary Goals

Memory Improvement

Many of the current "core" classes contains information that is only required for object-relational mapping. This type of metadata needlessly increases the amount of memory MOXy requires to run. This refactor will reduce the amount of memory MOXy requires to run.

Concepts

Package Splitting

This is when classes from the same package are distributed among different bundles. Modularity frameworks discourage splitting packages and therefore is something that we can not do.


Backwards Compatibility

Support applications written/compiled against previous versions of EclipseLink. Failing to be backwards compatible will have a negative impact on our user base. Anything less than binary compatibility will affect applications that include EclipseLink.

Binary Compatible

Applications compiled against EclipseLink before the footprint reduction will continue to work against EclipseLink after the footprint reduction.

Source Code Compatible

Applications compiled against EclipseLink before the footprint reduction will not continue to work against EclipseLink after the footprint reduction. The user won't need to modify their source code, but they will need to recompile it against the new version of EclipseLink.

Incompatible

The user would need to make changes to their code to work with the new version of EclipseLink. We could leverage the "package renamer" tool to make it easier for users to migrate their code to the new APIs.


Generics & Parameterized Types

This design makes use of generics, below is an example if you are not familiar with the mechanism in Java.

package demo;
 
import java.lang.reflect.Method;
 
public class Demo {
	private static String METHOD_NAME = "sample";
	private static Class<?>[] PARAMETER_TYPES = new Class[] {String.class};
 
	public static void main(String[] args) throws Exception {
		// Use Method - Test Method Can Be Called
		Integer a = new Foo().sample("A"); // YES
		Integer b = new Bar().sample("B"); // YES
		Integer c = new Baz().sample("C"); // YES
 
		// Reflection - Test Method Accessed Via Reflection
		hasMethod(Foo.class, METHOD_NAME, PARAMETER_TYPES); // YES
		hasMethod(Bar.class, METHOD_NAME, PARAMETER_TYPES); // NO
		hasMethod(Baz.class, METHOD_NAME, PARAMETER_TYPES); // YES
	}
 
	private static void hasMethod(Class<?> clazz, String methodName, Class<?>[] parameterTypes) {
		try {
			Method method = clazz.getMethod(methodName, parameterTypes);
			System.out.println(method);
		} catch(NoSuchMethodException e) {
			e.printStackTrace();
		}
	}
 
	// Regular Java Class
	static class Foo {
		public Integer sample(String string) {
			return null;
		}
	}
 
	// Parameterized Type
	static abstract class AbstractBar<RETURN, PARAMETER> {
		private RETURN value;
 
		public RETURN sample(PARAMETER parameter) {
			return value;
		}
	}	
 
	// Subclass of Parameterized type
	static class Bar extends AbstractBar<Integer, String>{
	}
 
	// Subclass of Parameterized type that overrides method from super class
	static class Baz extends AbstractBar<Integer, String> {
		@Override
		public Integer sample(String parameter) {
			return super.sample(parameter);
		}
	}
}


MOXy's DOM & SAX Platforms

MOXy contains two object-to-XML implementations: DOMPlatform and SAXPlatform. DOMPlatform was the first implementation and closely mirrors the mechanisms used by EclipseLink's object-to-relational mapping. SAXPlatform was introduced second as a performance improvement and now has almost completely replaced all usages of DOMPlatform.

Requirements

  1. Existing classes must remain binary compatible. This means that applications compiled against a previous version of EclipseLink must continue to run against the version of EclipseLink that implements the footprint reduction. Breaking backwards (binary) compatibility would require us to due a whole number version increment (i.e. 2.4.-> 3.0 and not 2.4 -> 2.5).


Design / Functionality

The following covers how approach #3 could be accomplished.

High Level

MOXy contains two mechanisms for converting objects to/from XML: DOMPlatform and SAXPlatform. DOMPlatform has strong roots in ORM processing (supports queries, change sets, etc) and is leveraged by EclipseLink EIS. SAXPlatform was introduced to optimize the binding use case as part of the JAXB implementation. The SAXPlatform shares much less logic with the ORM layer than the DOMPlatform does, but shares all the same dependencies. The goal of this feature is to extract only the code necessary to make the SAXPlatform work in order to support the JAXB use case.

  • Interfaces and abstract classes will be created to represent functionality common to core OXM and ORM behaviour.
  • Private OXM classes will be modified to interact with the new common interfaces/classes.
  • Existing core classes will implement/extend the new common interfaces/classes.
  • New MOXy classes will be created that implement the new common interfaces/classes.

Bundle Changes

  1. Introduce a new org.eclipse.persistence.bind bundle to contain common classes and interfaces and the light-weight OXM implementation.
  2. Modify the core bundle to depend on the new bind bundle.
  3. Move MOXy specify items from core into MOXy bundle (this is different from the new bind bundle)
  4. Move old OXM code into separate bundle for backwards compatibility (once core bundle no longer depends upon old OXM classes)

New Core Abstractions

Current (edit) Proposed (edit)
DesignDoc384399-Before.jpg            DesignDoc384399-Proposed.jpg

The following are core classes that are required by MOXy. These classes currently have dependencies on other ORM specific classes. As part of this feature new super classes will be created for each of these classes to contain the shared behaviour and state. The abstractions will maintain the same package structure under:

  • org.eclipse.persistence.core
  • org.eclipse.persistence.internal.core

Public Classes

This refactoring will affect the following public classes. Binary compatibility will be maintained as a result of this refactoring.

  1. org.eclipse.persistence.descriptors.ClassDescriptor
    1. getEventManager
    2. getInheritancePolicy
    3. getInstantiationPolicy
    4. getJavaClass
    5. getObjectBuilder
    6. getPrimaryKeyFieldNames
    7. getPrimaryKeyFields
    8. getTypedField
    9. hasEventManager
    10. hasInheritance
    11. setEventManager
    12. setInheritancePolicy
    13. setInstantiationPolicy
    14. setJavaClass
    15. setObjectBuilder
    16. setPrimaryKeyFieldNames
    17. setPimraryKeyFields
  2. org.eclipse.persistence.descriptors.DescriptorEvent
    1. setEventCode
    2. setRecord
    3. setSession
  3. org.eclipse.persistence.descriptors.DescriptorEventManager
    1. executeEvent
    2. hasAnyEventListeners
  4. org.eclipse.persistence.descriptors.InheritancePolicy
    1. classFromRow
    2. getAllChildDescriptors
    3. getClassIndicatorField
    4. getClassIndicatorMappings
    5. getDescriptor
    6. setClassIndicatorField
    7. setClassIndicatorMapping
    8. setDescriptor
  5. org.eclipse.persistence.mappings.DatabaseMapping
    1. getAttributeAccessor
    2. getAttributeClassification
    3. getAttributeValueFromObject
    4. getContainerPolicy
    5. getDescriptor
    6. getField
    7. getFields
    8. getReferenceDescriptor
    9. isAbstractCompositeCollectionMapping()
    10. isAbstractCompositeDirectCollectionMapping()
    11. isDirectToFieldMapping
    12. isReadOnly
    13. isWriteOnly
    14. setAttributeAccessor
    15. setAttributeValueInObject
    16. setDescriptor
    17. setFields
    18. valueFromObject
  6. org.eclipse.persistence.mappings.converters.Converter
    1. convertDataValueToObjectValue
    2. convertObjectValueToDataValue
    3. initialize
  7. org.eclipse.persistence.sessions.Project (TBD)
    1. TBD
  8. org.eclipse.persistence.sessions.Session (2 methods)
    1. getDescriptor
    2. getProperty

Internal Classes

This refactoring will affect the following internal classes. Even though these classes are technically internal they are probably leveraged by some of our users so binary compatibility will be maintained for these classes as well.

  1. org.eclipse.persistence.internal.databaseaccess.Platform (1 method)
    1. getConversionManager
  2. org.eclipse.persistence.internal.descriptors.InstantiationPolicy (1 method)
    1. buildNewInstance
  3. org.eclipse.persistence.internal.descriptors.ObjectBuilder (2 methods)
    1. createRecord
    2. extractPrimaryKeyFromObject
  4. org.eclipse.persistence.internal.helper.ClassConstants (5 constants)
    1. ABYTE (static constant)
    2. APBYTE (static constant)
    3. APCHAR (static constant)
    4. OBJECT (static constant)
    5. STRING (static constant)
  5. org.eclipse.persistence.internal.helper.ConversionManager (1 method)
    1. convertObject
  6. org.eclipse.persistence.internal.helper.DatabaseField (4 methods)
    1. getName
    2. setName
    3. getType
    4. setType
  7. org.eclipse.persistence.internal.helper.Helper (1 static method)
    1. cr (static)
  8. org.eclipse.persistence.internal.sessions.AbstractRecord (0 methods)
  9. org.eclipse.persistence.internal.sessions.AbstractSession (3 methods)
    1. getDatasourcePlatform
    2. getDescriptor
    3. getDescriptors

Areas Where We Need to Duplicate Code

Where there is an inheritance hierarchy a set of interfaces will be introduced in the core layer to represent the APIs required by both MOXy and ORM. The existing ORM classes will be modified to implement these interfaces and new implementations will be added in the MOXy layer.

  • org.eclipse.persistence.internal.queries.ContainerPolicy
    • org.eclipse.persistence.internal.queries.InterfaceContainerPolicy
      • org.eclipse.persistence.internal.queries.CollectionContainerPolicy
      • org.eclipse.persistence.internal.queries.MapContainerPolicy
  • org.eclipse.persistence.mappings.AttributeAccessor
    • org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor
    • org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor
    • Many more

Public OXM Classes

  • A mirror of the classes in the org.eclipse.persistence.oxm package will be created under the org.eclipse.persistence.bind package. XML specific classes will me put under a org.eclipse.persistence.bind.xml package.
  • The classes under the new org.eclipse.persistence.bind package will be refactored to use the APIs in the new bind and core packages.
  • The classes under the old org.eclipse.persistence.oxm package will be refactored to extend from or delegate to the new bind and core classes.

Internal OXM Classes (SAX Platform Related)

The following will be done to the classes in the internal.oxm package that are related to the SAX platform:

  • The will be updated to leverage the refactored classes from the previous steps.
  • The classes related to binding in general will be moved under the org.eclipse.persistence.internal.bind package.
  • The classes related to XML binding specifically will be moved under the org.eclipse.persistence.internal.bind.xml package.
  • The classes related to JSON binding specifically will be moved under the org.eclipse.persistence.internal.bind.json package.

Development Plan

Below is what the development plan would look like if we decide to maintain binary backwards compatibility of the native OXM APIs (see Open Issue #2).

Phase #1 - Introduce Core Abstraction Classes

Introduce the new core abstraction classes and change the existing core bundle to extend them.

Phase #2 - Introduce Core Interface Classes

Introduce the new core interfaces and change the corresponding core classes to implement them.

Phase #3 - Refactor the internal.oxm classes to depend on the classes created in Phases #1 and #2.

At this point the internal.oxm classes that are related to the SAX platform should only depend on classes in the oxm, internal.oxm, core, or internal.core packages.

Phase #4 - Pull internal.oxm Classes and Common Classes/Interfaces Into a New org.eclipse.persistence.bind Bundle

The internal.oxm classes and the new common classes/interfaces will form the basis of a new org.eclipse.persistence.bind bundle. The core bundle will be dependent on this new bundle. During this move the XML prefix on class names will be dropped, and the internal.oxm package will be renamed internal.bind. This is to reflect that MOXy now supports more than just object-to-XML mapping (MOXy also supports object-to-JSON mapping).

Phase #5 - Implement Light Weight OXM Version of Core Classes/Interfaces

A lightweight version of the core classes/interfaces will be implemented in the org.eclipse.persistence.bind package. Where possible the corresponding implementations in the org.eclipse.persistence.oxm package will be updated to extend their counterparts in the bind bundle so that there is as little code duplication as possible.

Phase #6 - Refactor OXM Classes to Extend From or Delegate To Bind Classes

Phase #7 - Update MOXy JAXB to Use org.eclipse.persistence.bind Bundle

Switch MOXy JAXB to use the bind bundle.

Phase #8 (Optional) - Update SDO to Use org.eclipse.persistence.bind Bundle

Switch SDO to use the bind bundle. We may or may not want to introduce a binary incompatibility into the SDO implementation by making this change.

Phase #9 (Optional) - Update Core to Use org.eclipse.persistence.bind Bundle

Switch core to use the bind bundle.

Phase #10 (Optional) - Move org.eclipse.persistence.oxm Classes into an oxm Bundle

Once the core bundle is no longer dependent upon the oxm classes they could be moved into there own bundle. This would reduce the footprint of the core bundle. The oxm classes would still be available for anyone that required them for backwards compatibility reasons.

Testing

Binary Compatible Testing

Testing would be required to ensure that binary compatibility is kept, for the areas we plan on maintaining binary compatibility.

API

Core Packages

The common core classes will be under the following packages. The final package structure will be reviewed once all the abstractions are known.

  • org.eclipse.persistence.core
  • org.eclipse.persistence.internal.core

Proposed Class Structure

New Abstractions (i.e. Descriptor)

A set of classes/interfaces will be created to represent the core functionality that is common to both object-to-XML and object-to-relational mapping. Type variables will be leveraged so that the OXM and ORM implementations can be further specialized.

package org.eclipse.persistence.internal.core;
 
public abstract class Descriptor<
    OBJECT_BUILDER extends ObjectBuilder,
    INHERITANCE_POLICY extends InheritancePolicy,
    INSTANTIATION_POLICY extends InstantiationPolicy> {
 
    OBJECT_BUILDER getObjectBuilder();
 
    INHERITANCE_POLICY getInheritancePolicy();
 
    INSTANTIATION_POLICY getInstantiationPolicy();
 
}

New OXM Classes

The new light weight MOXy will provide a new implementation of these core classes/interfaces (the class names below are for demonstration purposes only). The existing core OXM classes will continue to work (see below).

public class SmallXMLDescriptor extends Descriptor<SmallObjectBuilder, SmallInheritancePolicy, SmallInstantiationPolicy>, Cloneable, Serializable {

Existing Core Classes (i.e. ClassDescriptor)

The existing core classes will be modified to extends/implement these classes/interfaces supplying the appropriate type variables. Everything else about the core classes will stay the same ensuring backwards compatibility.

public class ClassDescriptor extends Descriptor<ObjectBuilder, InheritancePolicy, InstantiationPolicy>, Cloneable, Serializable {

Documentation

The following items will need to be documented:

  • What the binary incompatibilities are (if any).

Open Issues

This section lists the open issues that are still pending that must be decided prior to fully implementing this project's requirements.

Issue # Owner Description / Notes
1 Doug/Peter Does the implementation of this feature require us to bump the version number to 3.0?
2 Doug/Peter/Blaise Do we need to maintain binary compatibility of the native OXM APIs?

Decisions

This section lists decisions made. These are intended to document the resolution of open issues or constraints added to the project that are important.

Issue # Description / Notes Decision

Future Considerations

Remove Need for ASM Bundle

There are a few areas where MOXy makes use of the ASM bundle to generate bytecodes. Some feature work could be done to eliminate the need to generate these bytecodes and the ASM dependency could be dropped removing it from the install footprint.

Remove Need for ANTLR Bundle

Currently the ANTLR bundle is required to parse JSON documents. Once a standard JSON parser is available (see [1]), we can remove dependency on ANTLR from MOXy.

Move ORM Specific Packages to JPA Bundle

Using the Class Dependency Analyzer (CDA) tool I was able to determine that the following packages could be removed from the core bundle without affecting MOXy. Since we cannot split packages only whole packages can be moved. The classes in these packages represent approximately 170 KB of the core bundle.

  • org/eclipse/persistence/expressions/spatial
  • org/eclipse/persistence/internal/jpa/jpql
  • org/eclipse/persistence/platform/server/glassfish
  • org/eclipse/persistence/platform/server/jboss
  • org/eclipse/persistence/platform/server/oc4j
  • org/eclipse/persistence/platform/server/sap
  • org/eclipse/persistence/platform/server/sunas
  • org/eclipse/persistence/platform/server/was
  • org/eclipse/persistence/platform/server/wls
  • org/eclipse/persistence/services/glassfish
  • org/eclipse/persistence/services/jboss
  • org/eclipse/persistence/services/weblogic
  • org/eclipse/persistence/tools/file
  • org/eclipse/persistence/transaction
  • org/eclipse/persistence/transaction/glassfish
  • org/eclipse/persistence/transaction/jboss
  • org/eclipse/persistence/transaction/jotm
  • org/eclipse/persistence/transaction/oc4j
  • org/eclipse/persistence/transaction/sap
  • org/eclipse/persistence/transaction/sunas
  • org/eclipse/persistence/transaction/was
  • org/eclipse/persistence/transaction/wls

Enhancement Request (Contains Patch)

Footprint Reduction

Approximately 170 KB

Project Jigsaw

Is a standard module system being designed for the Java SE platform. It is being applied to the JDK itself. While this feature is not dependent on Jigsaw, care will be taken as to what modules we will need to depend on.

Back to the top