I thought Kathey/Dan's idea of generating copies of the common code
into two separate directories was interesting and solved a lot of problems,
and I thought it would be worthwhile to walk through this in a bit more
detail.

I took a look at all the relevant use cases I could think of and describe
the steps involved and what the user experience will be like.  Through
this effort I did find a couple of possible issues that may make us want
to think twice about this approach.  Perhaps others can think of ways around
these issues.  I have labelled issues uncovered with the tag <ISSUE> in
the text below, rather than try and summarize them here.


CREATING A COMMON CLASS

Say a developer wants to add a new class for logging.

The developer creates the package directory
java/common/org/apache/derby/common/logging

Under this directory she creates the new class Logger.  A simple
version is shown here.

===========

/**
  Derby class org.apache.derby.common.logging.Logger

  Copyright  yada yada
*/

package org.apache.derby.common.logging;

/**
* Class description
*/
public class Logger
{
 public void log(int level, String message)
 {
   // log this message
 }
}

===========

Note that this looks like a regular class.  This is so you
can edit it as a Java class in Java-aware IDEs.


BUILDING THE COMMON PACKAGE

The build script for the org/apache/derby/common directories
will not compile the class.  Instead, it invokes a build-time
tool that will perform the following actions for each class
in the org/apache/derby/common hierarchy:

- Create a copy of the file in java/common/org/apache/derby/engine/common
and change the package name in this copy to org.apache.derby.engine.common.

- Create a copy of the file in java/common/org/apache/derby/client/common
 and change the package name in this copy to org.apache.derby.client.common

- No lines will be added or removed.  This ensures that during debugging
 the line numbers in the generated code match the line numbers in the
original source.
- Compile both copies

The client/common and engine/common directories will be created if
they don't exist and will NOT be included in the svn directory structure.

ant clobber/clean will remove the client/common and engine/common
directories.

The generated source files will NOT be removed after compilation so
that developers can use a source debugger and so that you can navigate
to the source for browsing in Java-aware IDEs.  More on debugging below.

The classes under engine/common will be placed into derby.jar and
derbytools.jar.  The classes under client/common will be placed into
derbyclient.jar.

<ISSUE>
QUESTION: is there a need for mixed versions between the tools and
engine code?  If so we will need to generate a third package hierarchy
org.apache.derby.tools.common.*.
</ISSUE>



USING A COMMON CLASS

Code under java/engine, java/drda, java/tools and java/testing should
all import the classes under org.apache.derby.engine.common.

Code under java/client should import the classes under
org.apache.derby.client.common.

Common code unit tests can use either package hierarchy.



DEBUGGING A COMMON CLASS

Stack traces and debug stacks will point to the generated code
under engine/common or client/common depending on whether you
are debugging engine/tools/network code or client code.

<ISSUE>
If the debugger takes a developer to a common file and they see a bug,
the temptation will be to fix it in place and recompile.  This will
not work -- their changes will be lost when they run the build script.
The developer must instead go to the original source file in
org/apache/derby/common and fix it there.  I suspect this is going
to be confusing and annoying.

We could avoid this confusion by removing the generated source file
after compilation, but I think that this would be even more annoying,
as you wouldn't be able to do interactive source-level debugging.  Most
debugging is just stepping through code that you aren't modifying; you
just want to follow the logic.
</ISSUE>



CHECKING IN A COMMON CLASS

You check in the original source, NOT the generated source.
<ISSUE>
This is another potential source of errors.  A newbie developer
could check in the generated source, and we would have to clean
it out
</ISSUE>


RUNTIME WITH MIXED VERSIONS

If you have a 10.2 client and a 10.3 embedded driver in the same
VM, there is no conflict.  The 10.2 client code uses the 10.2
client/common classes and the 10.3 embedded/engine code uses the engine/common classes



Daniel John Debrunner wrote:

Kathey Marsden wrote:


I liked your idea of adding just the needed classes to the  existing
jars.  The trick  is to find a way to get Derby to always load the class
from the same jar file first, then no versioning is needed. Suddenly, creating separate package namespaces for the common package in the jars as last step of the jar build doesn't seem so weird to me.

I've been thinking about suggesting that as well, e.g. the same code
would be generated into two source java files in two (etc.) packages:

org.apache.derby.engine.common
org.apache.derby.client.common

As I said in an earlier e-mail, you can share at many levels, a lot
depends on why you are sharing? Is it to reduce development effort,
reduce static/runtime footprint, add confusion for the user?

Obfuscators rename packages all the time and are widely accepted.

And we already have generated code, so we handle that currently, ie. the
java files from the parsers.

It could even happen as a special  releasejar target so it wouldn't
confuse day to day development.

I don't agree with this, a single build process is much better, it
nmeans the normal development testing is in line with the released builds.


Dan.

begin:vcard
fn:David W Van Couvering
n:Van Couvering;David W
org:Sun Microsystems, Inc.;Database Technology Group
email;internet:[EMAIL PROTECTED]
title:Senior Staff Software Engineer
tel;work:510-550-6819
tel;cell:510-684-7281
x-mozilla-html:TRUE
version:2.1
end:vcard

Reply via email to