users@jpa-spec.java.net

[jpa-spec users] Re: [jsr338-experts] Re: Re: Re: schema generation proposed changes

From: Lance Andersen - Oracle <lance.andersen_at_oracle.com>
Date: Fri, 31 Aug 2012 16:21:44 -0400

On Aug 31, 2012, at 3:27 PM, Steve Ebersole wrote:

> Just to clarify... Do you mean :
>
> 1) DatabaseProductName
> 2) DatabaseMajorVersion
> 3) DatabaseMinorVersion


If the consensus is is that parsing is not desired then we should be able to get by with just the above.

When we talked internally I had a senior moment :-) and forgot about the DatabaseMajor/MinorVersion (thinking of the Driver flavor) and easy to overlook in the myriad of DatabaseMetaData methods even for me ;-)

I think the above should be sufficient and we would not need the DatabaseProductVersion

Best
Lance
>
> or
>
> 1) DatabaseProductName
> 2) DatabaseMajorVersion
> 3) DatabaseMinorVersion
> 4) DatabaseProductVersion
>
> ?
>
> Sorry if I was unclear before. I totally agree that I also think we need DatabaseProductName. What I was saying was that I thought using DatabaseMajorVersion and DatabaseMinorVersion was better than using just DatabaseProductVersion. Which it sounds like Lance is agreeing with.
>
>
> On Fri 31 Aug 2012 02:20:09 PM CDT, Linda DeMichiel wrote:
>> OK, thanks -- I will add additional properties for these.
>>
>> On 8/31/2012 7:03 AM, Lance Andersen - Oracle wrote:
>>> a few JDBC drivers can connect to multiple databases with the same
>>> driver such as jConnect to ASE, SQL Anywhere and Open
>>> Servers. In these cases just having the Major and minor version
>>> numbers might not be enough to distinguish the actual
>>> database you are connecting to. So you would probably need
>>> DatabaseProductName as well.
>>>
>>> I agree parsing could be a bit troublesome but either way you really
>>> need all 3 pieces of info if you do not leverage
>>> DatabaseProductVersion so you could use getDatabaseProductName,
>>> getDatabaseMajorVersion, getDatabaseMinorVersion
>>>
>>> Best
>>> Lance
>>> On Aug 30, 2012, at 11:56 PM, Steve Ebersole wrote:
>>>
>>>> Personally I think we get into trouble having both sets of versions.
>>>> What happens if the user specifies both
>>>> DatabaseProductVersion and DatabaseMajorVersion/DatabaseMinorVersion?
>>>>
>>>> To be completely honest, personally I'd much rather have access to
>>>> the DatabaseMetaData. But if thats not going to be
>>>> an option, I'd vote for just DatabaseMajorVersion and
>>>> DatabaseMinorVersion (optional).
>>>>
>>>> On Thu 30 Aug 2012 10:41:00 PM CDT, Linda DeMichiel wrote:
>>>>> Great, thanks!
>>>>>
>>>>> So, should we specify all 4 pieces of information?
>>>>>
>>>>>
>>>>> On 8/30/2012 8:09 PM, Steve Ebersole wrote:
>>>>>> Another is PostgreSQL adds "if exists" as an option for dropping
>>>>>> tables in 8.2 (major=8, minor=2) which did not exist in
>>>>>> 8.1 or earlier
>>>>>>
>>>>>>
>>>>>> On Thu 30 Aug 2012 10:04:35 PM CDT, Steve Ebersole wrote:
>>>>>>> Well a real simple example is that Derby supports sequences after
>>>>>>> 10.6, but not before. So there
>>>>>>> DatabaseMetaData#getDatabaseMajorVersion=10 and
>>>>>>> DatabaseMetaData#getDatabaseMinorVersion=6. Even if the Derby driver
>>>>>>> were to report the DatabaseMetaData#getDatabaseProductVersion="10.6"
>>>>>>> or somesuch, relying on being able to parse that into ints to be
>>>>>>> able
>>>>>>> to do range checks make me nervous, especially when JDBC already
>>>>>>> offers means to know the major/minor.
>>>>>>>
>>>>>>> And thats just one example that came to me immediately.
>>>>>>>
>>>>>>> On Thu 30 Aug 2012 07:24:45 PM CDT, Linda DeMichiel wrote:
>>>>>>>> Hi Steve,
>>>>>>>>
>>>>>>>> I'd like to understand this better, as the info I have from our
>>>>>>>> team
>>>>>>>> here
>>>>>>>> indicates that database produce name together with version (in the
>>>>>>>> worst case)
>>>>>>>> would be sufficient. Do we need all four properties to accommodate
>>>>>>>> the range
>>>>>>>> of drivers/databases?
>>>>>>>>
>>>>>>>> thanks,
>>>>>>>>
>>>>>>>> -Linda
>>>>>>>>
>>>>>>>>
>>>>>>>> On 8/29/2012 7:30 AM, Steve Ebersole wrote:
>>>>>>>>> As far as:
>>>>>>>>>
>>>>>>>>> javax.persistence.database-product-name,
>>>>>>>>> javax.persistence.database-product-version,
>>>>>>>>>
>>>>>>>>> I'd really rather see major/minor version used:
>>>>>>>>>
>>>>>>>>> (int) java.sql.DatabaseMetaData#getDatabaseMajorVersion
>>>>>>>>> (int) java.sql.DatabaseMetaData#getDatabaseMinorVersion
>>>>>>>>>
>>>>>>>>> as opposed to the proposed:
>>>>>>>>>
>>>>>>>>> (String) java.sql.DatabaseMetaData#getDatabaseProductVersion
>>>>>>>>>
>>>>>>>>> For one Hibernate already uses those 2 ;) For another its more
>>>>>>>>> indicative of what is/isn't available consistently across
>>>>>>>>> databases.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 07/23/2012 06:55 PM, Linda DeMichiel wrote:
>>>>>>>>>> Here's an updated version of my earlier schema generation
>>>>>>>>>> proposal,
>>>>>>>>>> broken out as to proposed spec changes. You should hopefully find
>>>>>>>>>> this considerably more flexible and detailed than the earlier
>>>>>>>>>> draft.
>>>>>>>>>>
>>>>>>>>>> -Linda
>>>>>>>>>>
>>>>>>>>>> ----------------------------
>>>>>>>>>>
>>>>>>>>>> Proposed spec changes:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> New Section: Schema Generation [to follow section 9.3]
>>>>>>>>>>
>>>>>>>>>> Schema generation may either happen prior to application
>>>>>>>>>> deployment or
>>>>>>>>>> when the entity manager factory is created as part of the
>>>>>>>>>> application
>>>>>>>>>> deployment and initialization process.
>>>>>>>>>>
>>>>>>>>>> * In Java EE environments, the container may call the
>>>>>>>>>> PersistenceProvider generateSchema method separately from and/or
>>>>>>>>>> prior to the creation of the entity manager factory for the
>>>>>>>>>> persistence unit, or the container may pass additional
>>>>>>>>>> information to the createContainerEntityManagerFactory call to
>>>>>>>>>> cause schema generation to happen as part of the entity manager
>>>>>>>>>> factory creation and application initialization process. The
>>>>>>>>>> information passed to these methods determines whether the
>>>>>>>>>> generation of schemas and/or tables occurs directly in the target
>>>>>>>>>> database, or whether DDL scripts for schema generation are
>>>>>>>>>> created, or both.
>>>>>>>>>>
>>>>>>>>>> * In Java SE environments, the application may call the
>>>>>>>>>> Persistence
>>>>>>>>>> generateSchema method separately from and/or prior to the
>>>>>>>>>> creation
>>>>>>>>>> of the entity manager factory or may pass information to the
>>>>>>>>>> createEntityManagerFactory method to cause schema generation to
>>>>>>>>>> occur as part of the entity manager factory creation.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> The application may provide DDL scripts to be used for schema
>>>>>>>>>> generation, and package these scripts as part of the persistence
>>>>>>>>>> unit
>>>>>>>>>> or specify URLs corresponding to the location of such scripts. In
>>>>>>>>>> Java EE environments, such scripts may be executed by the
>>>>>>>>>> container,
>>>>>>>>>> or the container may direct the persistence provider to
>>>>>>>>>> execute the
>>>>>>>>>> scripts; in Java SE environments, the execution of the scripts is
>>>>>>>>>> the
>>>>>>>>>> responsibility of the persistence provider. In the absence of the
>>>>>>>>>> specification of scripts, schema generation, if requested,
>>>>>>>>>> will be
>>>>>>>>>> determined by the object/relational metadata of the persistence
>>>>>>>>>> unit.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> The following standard properties are defined for use in schema
>>>>>>>>>> generation. In Java EE environments these properties are
>>>>>>>>>> passed by
>>>>>>>>>> the container in the Map argument to the PersistenceProvider
>>>>>>>>>> generateSchema method or createContainerEntityManagerFactory
>>>>>>>>>> method.
>>>>>>>>>> In Java SE environments, they are passed in the Map argument
>>>>>>>>>> to the
>>>>>>>>>> Persistence generateSchema or createEntityManagerFactory method.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> javax.persistence.schema-generation-target:
>>>>>>>>>>
>>>>>>>>>> The schema-generation-target property specifies whether the
>>>>>>>>>> schema
>>>>>>>>>> is to be created in the database, whether scripts are to be
>>>>>>>>>> generated, or both.
>>>>>>>>>>
>>>>>>>>>> values for this property: DATABASE, SCRIPTS, DATABASE_AND_SCRIPTS
>>>>>>>>>> [Open Issue: introduce for these enum or use strings? Better
>>>>>>>>>> names??]
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> javax.persistence.schema-generation-action:
>>>>>>>>>>
>>>>>>>>>> The schema-generation-action property is used to specify the
>>>>>>>>>> action
>>>>>>>>>> to be taken by the persistence provider. If the
>>>>>>>>>> schema-generation-target property is not specified, no action
>>>>>>>>>> must
>>>>>>>>>> be taken.
>>>>>>>>>>
>>>>>>>>>> values for this property: NONE, CREATE, DROP_AND_CREATE, DROP
>>>>>>>>>> [Open Issue: enum strings ("none", "create",
>>>>>>>>>> "drop-and-create",...)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> javax.persistence.create-database-schemas
>>>>>>>>>>
>>>>>>>>>> In Java EE environments, it is anticipated that the Java EE
>>>>>>>>>> platform provider may wish to control the creation of database
>>>>>>>>>> schemas rather than delegate this task to the persistence
>>>>>>>>>> provider.
>>>>>>>>>> The create-database-schemas property specifies whether the
>>>>>>>>>> persistence provider is to create the database schema(s) in
>>>>>>>>>> addition to creating database objects such as tables, sequences,
>>>>>>>>>> constraints, etc. The value of this boolean property should be
>>>>>>>>>> set
>>>>>>>>>> to true if the persistence provider is to create schemas in the
>>>>>>>>>> database or to generate DDL which is to contain "CREATE SCHEMA"
>>>>>>>>>> commands. If this property is not supplied, the provider should
>>>>>>>>>> not attempt to create database schemas. This property may be
>>>>>>>>>> specified in Java SE environments as well.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> javax.persistence.ddl-create-script-target,
>>>>>>>>>> javax.persistence.ddl-drop-script-target:
>>>>>>>>>>
>>>>>>>>>> If scripts are to be generated, the target locations for the
>>>>>>>>>> writing of these scripts must be specified. These targets may
>>>>>>>>>> take
>>>>>>>>>> the form of either Writers or strings designating URLs. The
>>>>>>>>>> persistence provider must produce both create and drop scripts if
>>>>>>>>>> the corresponding DDL targets are specified. This is independent
>>>>>>>>>> of whether a drop action is included in the value passed for the
>>>>>>>>>> schema-generation-action property. If the
>>>>>>>>>> schema-generation-target
>>>>>>>>>> property specifies scripts and script targets are not specified,
>>>>>>>>>> the IllegalArgumentException should be thrown by the provider.
>>>>>>>>>>
>>>>>>>>>> ddl-create-script-target: a Writer configured for the persistence
>>>>>>>>>> provider for output of the DDL script or a string specifying
>>>>>>>>>> the URL for the DDL script. This property should only be
>>>>>>>>>> specified if scripts are to be generated.
>>>>>>>>>>
>>>>>>>>>> ddl-drop-script-target: a Writer configured for the persistence
>>>>>>>>>> provider for output of the DDL script or a string specifying the
>>>>>>>>>> URL for the DDL script. This property should only be specified
>>>>>>>>>> if scripts are to be generated.
>>>>>>>>>> [Suggestions for better names ??]
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> javax.persistence.database-product-name,
>>>>>>>>>> javax.persistence.database-product-version,
>>>>>>>>>>
>>>>>>>>>> If scripts are to be generated by the persistence provider and a
>>>>>>>>>> connection to the target database is not supplied, the
>>>>>>>>>> javax.persistence.database-product-name property must be
>>>>>>>>>> specified. The value of this property should be the value
>>>>>>>>>> returned for the target database by the JDBC DatabaseMetaData
>>>>>>>>>> method getDatabaseProductName. If sufficient database version
>>>>>>>>>> information is not included in the result of this method, the
>>>>>>>>>> database-product-version property should also be specified, and
>>>>>>>>>> should contain the value returned by the JDBC
>>>>>>>>>> getDatabaseProductVersion method.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> javax.persistence.ddl-create-script-source,
>>>>>>>>>> javax.persistence.ddl-drop-script-source:
>>>>>>>>>>
>>>>>>>>>> The ddl-create-script-source and ddl-drop-script-source
>>>>>>>>>> properties
>>>>>>>>>> are used for script execution. In Java EE container environments,
>>>>>>>>>> it is generally expected that the container will be responsible
>>>>>>>>>> for executing DDL scripts, although the container is permitted to
>>>>>>>>>> delegate this task to the persistence provider. If DDL scripts
>>>>>>>>>> are to be used in Java SE environments or if the Java EE
>>>>>>>>>> container
>>>>>>>>>> delegates the execution of scripts to the persistence provider,
>>>>>>>>>> these properties must be specified. The script sources may take
>>>>>>>>>> the form of either Readers or strings designating URLs.
>>>>>>>>>>
>>>>>>>>>> ddl-create-script-source: a Reader configured for reading of the
>>>>>>>>>> DDL script or a string specifying the URL for the DDL script.
>>>>>>>>>>
>>>>>>>>>> ddl-drop-script-source: a Reader configured for reading of the
>>>>>>>>>> DDL
>>>>>>>>>> script or a string specifying the URL for the DDL script.
>>>>>>>>>> [Suggestions for better names ??]
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> javax.persistence.sql-load-script-source:
>>>>>>>>>>
>>>>>>>>>> A data load script may be supplied as part of the persistence
>>>>>>>>>> unit. In Java EE container environments, it is generally expected
>>>>>>>>>> that the container will be responsible for executing data load
>>>>>>>>>> scripts, although the container is permitted to delegate this
>>>>>>>>>> task
>>>>>>>>>> to the persistence provider. If a load script is to be used in
>>>>>>>>>> Java SE environments or if the Java EE container delegates the
>>>>>>>>>> execution of the load script to the persistence provider, this
>>>>>>>>>> property must be specified. The script source may take the form
>>>>>>>>>> of either a Reader or a string designating a URL.
>>>>>>>>>>
>>>>>>>>>> sql-load-script-source: a Reader configured for reading of the
>>>>>>>>>> SQL
>>>>>>>>>> load script for database initialization or a string specifying
>>>>>>>>>> the URL for the script.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> javax.persistence.schema-generation-connection:
>>>>>>>>>>
>>>>>>>>>> JDBC connection to be used for schema generation. This is
>>>>>>>>>> intended
>>>>>>>>>> for use in Java EE environments, where the platform provider may
>>>>>>>>>> want to control the database privileges that are available to the
>>>>>>>>>> persistence provider. This connection is provided by the
>>>>>>>>>> container,
>>>>>>>>>> and should be closed by the container when the schema generation
>>>>>>>>>> request or entity manager factory creation completes. The
>>>>>>>>>> connection provided must have credentials sufficient for the
>>>>>>>>>> persistence provider to carry out the requested actions. If this
>>>>>>>>>> property is not specified, the persistence provider should use
>>>>>>>>>> the
>>>>>>>>>> DataSource that has otherwise been provided.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> 9.4.1 PersistenceProvider Interface:
>>>>>>>>>>
>>>>>>>>>> New method:
>>>>>>>>>>
>>>>>>>>>> /**
>>>>>>>>>> * Create database schemas and/or tables and/or create DDL
>>>>>>>>>> * scripts as determined by the supplied properties
>>>>>>>>>> *
>>>>>>>>>> * @param info metadata for use by the persistence provider
>>>>>>>>>> * @param map properties for schema generation; these
>>>>>>>>>> * may also contain provider-specific properties
>>>>>>>>>> * @throws PersistenceException if insufficient or inconsistent
>>>>>>>>>> * configuration information is provided or if schema
>>>>>>>>>> * generation otherwise fails.
>>>>>>>>>> */
>>>>>>>>>> public void generateSchema(PersistenceUnitInfo info, Map map)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> 9.6 Persistence Class
>>>>>>>>>>
>>>>>>>>>> New method:
>>>>>>>>>>
>>>>>>>>>> /**
>>>>>>>>>> * Create database schemas and/or tables and/or create DDL
>>>>>>>>>> * scripts as determined by the supplied properties
>>>>>>>>>> *
>>>>>>>>>> * @param persistenceUnitName the name of the persistence unit
>>>>>>>>>> * @param map properties for schema generation; these may also
>>>>>>>>>> * contain provider-specific properties. The values of
>>>>>>>>>> * these properties override any values that may have been
>>>>>>>>>> * configured elsewhere.
>>>>>>>>>> * @throws PersistenceException if insufficient or inconsistent
>>>>>>>>>> * configuration information is provided or if schema
>>>>>>>>>> * generation otherwise fails.
>>>>>>>>>> */
>>>>>>>>>> public void generateSchema(String persistenceUnitName, Map
>>>>>>>>>> properties)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> -----------------------
>>>>>>>>>>
>>>>>>>>>> Section 8.2.1 persistence.xml file
>>>>>>>>>>
>>>>>>>>>> To be added to section 8.2.1:
>>>>>>>>>>
>>>>>>>>>> Scripts for use in schema generation and bulk loading of data
>>>>>>>>>> may be
>>>>>>>>>> packaged as part of the persistence unit.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> To be added to Section 8.2.1.9 (properties):
>>>>>>>>>>
>>>>>>>>>> Scripts for use in schema generation are specified using the
>>>>>>>>>> ddl-create-script and ddl-drop-script elements. A script to
>>>>>>>>>> specify
>>>>>>>>>> SQL for the bulk loading of data may be specified by the
>>>>>>>>>> sql-load-script element. These scripts may be packaged as part of
>>>>>>>>>> the
>>>>>>>>>> persistence unit or designated by URL strings.
>>>>>>>>>>
>>>>>>>>>> <xsd:element name="database-scripts" type="database-scripts-type"
>>>>>>>>>> minOccurs="0"/>
>>>>>>>>>>
>>>>>>>>>> <xsd:complexType name="database-scripts-type">
>>>>>>>>>> <xsd:sequence>
>>>>>>>>>> <xsd:element name="ddl-create-script" type="xsd:string"/>
>>>>>>>>>> <xsd:element name="ddl-drop-script" type="xsd:string"
>>>>>>>>>> minOccurs="0"/>
>>>>>>>>>> <xsd:element name="sql-load-script" type="xsd:string"
>>>>>>>>>> minOccurs="0"/>
>>>>>>>>>> </xsd:sequence>
>>>>>>>>>> </xsd:complexType>
>>>>>>>>>>
>>>>>>>>>> [Open Issue: do we want to require a drop-script if a
>>>>>>>>>> create-script
>>>>>>>>>> has been provided?]
>>>>>>>>>>
>>>>>>>>>> -----------
>>>>>>>>>>
>>>>>>>>>> Chapter 11:
>>>>>>>>>>
>>>>>>>>>> New annotations for use in schema generation:
>>>>>>>>>>
>>>>>>>>>> @Target({}) @Retention(RUNTIME)
>>>>>>>>>> public @interface Index {
>>>>>>>>>> String name() default "";
>>>>>>>>>> String columnList();
>>>>>>>>>> boolean unique() default false; // should this be here or just
>>>>>>>>>> use
>>>>>>>>>> UniqueConstraints?
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> columnList syntax follows that of the OrderBy annotation:
>>>>>>>>>>
>>>>>>>>>> columnList::= indexColumn [, indexColumn]*
>>>>>>>>>> indexColumn::= columnName [ASC | DESC]
>>>>>>>>>>
>>>>>>>>>> If ASC or DESC is not specified, ASC is assumed
>>>>>>>>>>
>>>>>>>>>> Index[] indexes() default {};
>>>>>>>>>> is to be added to Table, SecondaryTable, CollectionTable,
>>>>>>>>>> JoinTable,
>>>>>>>>>> and
>>>>>>>>>> TableGenerator
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> /**
>>>>>>>>>> * Provides for defining a foreign key constraint or for
>>>>>>>>>> overriding
>>>>>>>>>> * or disabling the persistence provider's default foreign key
>>>>>>>>>> * definition.
>>>>>>>>>> */
>>>>>>>>>> @Target({}) @Retention(RUNTIME)
>>>>>>>>>> public @interface ForeignKey {
>>>>>>>>>> String name() default "";
>>>>>>>>>> String foreignKeyDefinition() default "";
>>>>>>>>>> boolean disableForeignKey() default false;
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> The syntax used in the foreignKeyDefinition element should follow
>>>>>>>>>> the
>>>>>>>>>> SQL syntax used by the target database for foreign key
>>>>>>>>>> constraints.
>>>>>>>>>> E.g., this would likely be similar to the following:
>>>>>>>>>>
>>>>>>>>>> FOREIGN KEY ( <COLUMN expression> {, <COLUMN expression>}... )
>>>>>>>>>> REFERENCES <TABLE identifier> [ ( <COLUMN expression> {, <COLUMN
>>>>>>>>>> expression>}... ) ]
>>>>>>>>>> [ ON UPDATE <referential action> ]
>>>>>>>>>> [ ON DELETE <referential action> ]
>>>>>>>>>>
>>>>>>>>>> If disableForeignKey is specified as true, the provider must not
>>>>>>>>>> generate
>>>>>>>>>> a foreign key constraint.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> The following is to be added to JoinColumn, JoinColumns,
>>>>>>>>>> MapKeyJoinColumn,
>>>>>>>>>> MapKeyJoinColumns, PrimaryKeyJoinColumn and
>>>>>>>>>> PrimaryKeyJoinColumns:
>>>>>>>>>>
>>>>>>>>>> ForeignKey foreignKey() default @ForeignKey();
>>>>>>>>>>
>>>>>>>>>>
>>>
>>> <http://oracle.com/us/design/oracle-email-sig-198324.gif>
>>> <http://oracle.com/us/design/oracle-email-sig-198324.gif>Lance
>>> Andersen| Principal Member of Technical Staff |
>>> +1.781.442.2037
>>> Oracle Java Engineering
>>> 1 Network Drive
>>> Burlington, MA 01803
>>> Lance.Andersen_at_oracle.com <mailto:Lance.Andersen_at_oracle.com>
>>>


Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037
Oracle Java Engineering
1 Network Drive
Burlington, MA 01803
Lance.Andersen_at_oracle.com