Top Description Fields Constructors Methods
org.apache.derby.impl.services.bytecode

public Class BCJava

extends Object
implements JavaFactory, CacheableFactory, ModuleControl
Class Inheritance
All Implemented Interfaces
org.apache.derby.iapi.services.monitor.ModuleControl, org.apache.derby.iapi.services.cache.CacheableFactory, org.apache.derby.iapi.services.compiler.JavaFactory
Imports
org.apache.derby.iapi.services.compiler.JavaFactory, .ClassBuilder, .MethodBuilder, org.apache.derby.iapi.services.loader.ClassFactory, org.apache.derby.iapi.services.classfile.ClassHolder, .VMDescriptor, org.apache.derby.iapi.services.cache.Cacheable, .CacheableFactory, .CacheFactory, .CacheManager, org.apache.derby.iapi.services.monitor.Monitor, .ModuleControl, org.apache.derby.shared.common.error.StandardException, org.apache.derby.shared.common.sanity.SanityManager, java.util.Properties, .Hashtable

Debugging problems with generated classes

When the code has been generated incorrectly, all sorts of odd things can go wrong. This is one recommended approach to finding the problem.

First, turn on ByteCodeGenInstr and DumpClassFile. Look for missing files (right now they are consecutively numbered by the activation class builder; later on they won't be, but BytCodeGenInstr dumps messages about the classes it has). Look at the log to make sure that all "GEN starting class/method" messages are paired with a "GEN ending class/method" message. If a file is missing or the pairing is missing, then something went wrong when the system tried to generate the bytecodes. Resort to your favorite debugging tool to step through the faulty statement.

If you get class files but the system crashes on you (I had an OS segmentation fault once) or you get funny messages like JDBC Excpetion: ac5 where ac5 is just the name of a generated class, then one of the following is likely:

The best way to locate the problem here is to do this (replace ac5.class with the name of your class file):
  1. javap -c -v ac5 > ac5.gp
    if javap reports "Class not found", and the file ac5.class does exist in the current directory, then the .class file is probably corrupt. Try running mocha on it to see if that works. The problem will be in the code that generates the entries for the class file -- most likely the ConstantPool is bad, an attribute got created incorrectly, or perhaps the instruction streams are goofed up.
  2. java mocha.Decompiler ac5.class
    if mocha cannot create good java source, then you really need to go back and examine the calls creating the java constructs; a parameter might have been null when it should have, a call to turn an expression into a statement may be missing, or something else may be wrong.
  3. mv ac5.mocha ac5.java
  4. vi ac5.java ; you will have to fix any new SQLBoolean(1, ...) calls to be new SQLBoolean(true, ...). Also mocha occasionally messes up other stuff too. Just iterate on it until it builds or you figure out what is wrong with the generated code.
  5. javac ac5.java
  6. javap -v -c ac5 > ac5.jp
  7. sed '1,$s/#[0-9]* </# </' ac5.gp > ac5.gn
  8. sed '1,$s/#[0-9]* </# </' ac5.jp > ac5.jn
    These seds are to get rid of constant pool entry numbers, which will be wildly different on the two files.
  9. vdiff32 ac5.gn ac5.jn
    this tool shows you side-by-side diffs. If you change to the window that interleaves the diffs, you can see the length of the line. Look for places where there are invokevirtual vs. invokeinterface differences, differences in the class name of a field, differences in the class name of a method parameter or return type. The generated code will* have some unavoidable differences from the compiled code, such as:
    • it will have goto's at the end of try blocks rather than return's.
    • it will do a getstatic on a static final field rather than inlining the static final field's value
    • it will have more checkcast's in it, since it doesn't see if the checkcast will always succeed and thus remove it.
    Once you find a diff, you need to track down where the call was generated and modify it appropriately: change newMethodCall to newInterfaceMethodCall; add newCastExpression to get a argument into the right type for the parameter; ensure the return type given for the method is its declared return type.
See Also
org.apache.derby.iapi.services.compiler.JavaFactory

Field Summary

Modifier and TypeField and Description
private CacheManager

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
public void
boot(boolean
True if the database should be created
create
,
Properties
Configuration properties
properties
)

Implements org.apache.derby.iapi.services.monitor.ModuleControl.boot.

Start this module.

public Cacheable
public ClassBuilder

Returns:

the class builder.
newClassBuilder
(ClassFactory
ClassFactory to be used for class resolution (debug only) and loading of the generated class.
cf
,
String
the name of the package the class is in. null if it is in the default package.
packageName
,
int
the | of the Modifiers constants representing the visibility and control of this method.
modifiers
,
String
the name of the class or interface
className
,
String
the name of the superclass or superinterface
superClass
)

Implements org.apache.derby.iapi.services.compiler.JavaFactory.newClassBuilder.

a class.</verbatim>

private static Object
startSystemModule(final String factoryInterface)

Must be private so that user code can't call this entry point.

public void
pack-priv Type

Returns:

The java VM type ID
type
(String
The java type name to translate to a java VM type id
javaType
)

Get the VM Type ID that corresponds with the given java type name.

pack-priv String
pack-priv static short
vmTypeId(String vmTypeS)

Map vm types as strings to vm types as the VM handles, with int ids.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

vmTypeIdCacheback to summary
private CacheManager vmTypeIdCache

Constructor Detail

BCJavaback to summary
public BCJava()

Method Detail

bootback to summary
public void boot(boolean create, Properties properties) throws StandardException

Implements org.apache.derby.iapi.services.monitor.ModuleControl.boot.

Start this module. We need a read/write version of the class utilities

Parameters
create:boolean

Doc from org.apache.derby.iapi.services.monitor.ModuleControl.boot.

True if the database should be created

properties:Properties

Doc from org.apache.derby.iapi.services.monitor.ModuleControl.boot.

Configuration properties

Exceptions
StandardException:
standard Derby policy
newCacheableback to summary
public Cacheable newCacheable(CacheManager cm)

Implements org.apache.derby.iapi.services.cache.CacheableFactory.newCacheable.

newClassBuilderback to summary
public ClassBuilder newClassBuilder(ClassFactory cf, String packageName, int modifiers, String className, String superClass)

Implements org.apache.derby.iapi.services.compiler.JavaFactory.newClassBuilder.

a class. Once it is created, fields, methods, interfaces, static initialization code, and constructors can be added to it. Java: package #packageName; #modifiers #className extends #superClass { } // modifiers is the | of the JVM constants for // the modifiers such as static, public, etc. See java.lang.reflect.Modifiers

Parameters
cf:ClassFactory

Doc from org.apache.derby.iapi.services.compiler.JavaFactory.newClassBuilder.

ClassFactory to be used for class resolution (debug only) and loading of the generated class.

packageName:String

the name of the package the class is in. null if it is in the default package.

modifiers:int

the | of the Modifiers constants representing the visibility and control of this method.

className:String

the name of the class or interface

superClass:String

the name of the superclass or superinterface

Returns:ClassBuilder

the class builder.

startSystemModuleback to summary
private static Object startSystemModule(final String factoryInterface) throws StandardException

Must be private so that user code can't call this entry point.

stopback to summary
public void stop()

Implements org.apache.derby.iapi.services.monitor.ModuleControl.stop.

Stop this module. In this case, nothing needs to be done.

typeback to summary
pack-priv Type type(String javaType)

Get the VM Type ID that corresponds with the given java type name. This uses the cache of VM type ids.

Parameters
javaType:String

The java type name to translate to a java VM type id

Returns:Type

The java VM type ID

vmTypeback to summary
pack-priv String vmType(BCMethodDescriptor md)
vmTypeIdback to summary
pack-priv static short vmTypeId(String vmTypeS)

Map vm types as strings to vm types as the VM handles, with int ids. Used in mapping opcodes based on type of operand/stack entry available.