db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "David W. Van Couvering" <David.Vancouver...@Sun.COM>
Subject Re: VOTE: Approach for sharing code
Date Fri, 09 Sep 2005 03:42:20 GMT
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.
>
>  
>

Mime
View raw message