You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-user@db.apache.org by De...@richer.ca on 2004/11/03 19:04:19 UTC
OJB XDoclet Module doesn't support multiple projects
Hi,
I have been using OJB since January and I use the XDoclet module to build
the repository_user.xml file. Everything has been going well, but
recently I have been splitting our code base up into several subprojects
and that has proven to be a much more difficult task than I originally
anticipated. For simplicity, lets assume I am splitting into only 2
projects ... one called "Common" and another called "My Project".
Consider the following example ... one class in the My Project project
(Foo) is referencing a class in the Common project (Bar):
/**
* @ojb.class table="Foo"
*
* @ojb.field
* name="barKey"
* column="BAR_KEY"
* jdbc-type="CHAR"
* length="8"
*/
public class Foo {
/**
* @ojb.reference foreignkey="barKey"
*/
private Bar bar;
}
According to the documentation for the ojbdoclet task:
checks : none | basic | strict (default)
The amount of the checks performed. Per default, strict checks are
performed which means that for instance classes specified in an attribute
(e.g. collection-class, row-reader etc.) are loaded from the classpath and
checked. So in this mode it is necessary to have OJB as well as the
processed classes on the classpath (using the classpathref attribute of
the taskdef ant task above). If this is for some reason not possible, then
use basic which performs most of the checks but does not load classes from
the classpath. none does not perform any checks so use it with care and
only if really necessary (in this case it would be helpful if you would
post the problem to the ojb-user mailing list).
I have the following in my ant build file:
<path id="classpath">
<fileset dir="${common.build.dir}" />
</path>
<target
name="repository-files"
depends="compile"
description="Update the repository mapping files for
ObJect-relational Bridge">
<taskdef
name="ojbdoclet"
classname="xdoclet.modules.ojb.OjbDocletTask"
classpathref="classpath"/>
<ojbdoclet destdir="${src.java.dir}">
<fileset dir="${src.java.dir}" />
<ojbrepository destinationFile=
"repository_user.xml"/>
</ojbdoclet>
</target>
The XDoclet module *does* load classes from the classpath identified by
the "classpathref" attribute of the taskdef, but the xdoclet module is not
looking for the class itself but the *class descriptor* for Bar (which is
sitting in Common's repository_user.xml file). Because it can't find the
class descriptor I get the following error message:
<<The class Bar referenced by bar in class Foo is unknown or not
persistent>>
So, as a workaround I changed the mapping for Foo to this:
public class Foo {
/**
* @ojb.reference
* foreignkey="barKey"
* class-ref="Bar"
*/
private Bar bar;
}
and disabled checks by setting checks="none" on the ojbdoclet call in my
ant build script. This seems to fix the problem (i.e. it no longer tries
to load Bar, but it does use the explicit class-ref provided). However,
by setting checks to "none", none of the class references to other classes
that are in "My Project" resolve properly ... I get a repository_user.xml
file with classref="". I've decompiled and read through some of the
xdoclet module's source code and it seems that the method "ensureClassRef"
of ReferenceDescriptorConstraints has a side-effect of setting the class
name of the classref, but this never occurs if checks is set to none.
If anyone else has experience splitting an OJB project across multiple
subprojects, please let me know how you solved this problem. Currently, I
am using a hacked version of the OJB XDoclet module with a modified
"ensureClassRef" method that *always* sets the classref regardless of the
check level. But really, there should be a way to load reference
descriptors from another descriptor repository as part of the ojbdoclet
task. Maybe something like this:
<ojbdoclet destdir="${src.java.dir}">
<externalDescriptorRepository>
<fileset dir="${common.dir}">
<include
name="repository_user.xml" />
</fileset>
</externalDescriptorRepository>
<fileset dir="${src.java.dir}" />
<ojbrepository destinationFile=
"repository_user.xml"/>
</ojbdoclet>
The descriptor repositories identified by the nested fileset element would
have to be merged into the global repository before checking the
constraints of the java files found in the ${src.java.dir} ...
Thanks,
Phil Denis
Re: OJB XDoclet Module doesn't support multiple projects
Posted by Thomas Dudziak <to...@first.fhg.de>.
DenisP@richer.ca wrote:
>Hi,
>
>I have been using OJB since January and I use the XDoclet module to build
>the repository_user.xml file. Everything has been going well, but
>recently I have been splitting our code base up into several subprojects
>and that has proven to be a much more difficult task than I originally
>anticipated. For simplicity, lets assume I am splitting into only 2
>projects ... one called "Common" and another called "My Project".
>
>Consider the following example ... one class in the My Project project
>(Foo) is referencing a class in the Common project (Bar):
>
>
<snip/>
>The XDoclet module *does* load classes from the classpath identified by
>the "classpathref" attribute of the taskdef, but the xdoclet module is not
>looking for the class itself but the *class descriptor* for Bar (which is
>sitting in Common's repository_user.xml file). Because it can't find the
>class descriptor I get the following error message:
><<The class Bar referenced by bar in class Foo is unknown or not
>persistent>>
>
>So, as a workaround I changed the mapping for Foo to this:
>public class Foo {
> /**
> * @ojb.reference
> * foreignkey="barKey"
> * class-ref="Bar"
> */
> private Bar bar;
>}
>
>and disabled checks by setting checks="none" on the ojbdoclet call in my
>ant build script. This seems to fix the problem (i.e. it no longer tries
>to load Bar, but it does use the explicit class-ref provided). However,
>by setting checks to "none", none of the class references to other classes
>that are in "My Project" resolve properly ... I get a repository_user.xml
>file with classref="". I've decompiled and read through some of the
>xdoclet module's source code and it seems that the method "ensureClassRef"
>of ReferenceDescriptorConstraints has a side-effect of setting the class
>name of the classref, but this never occurs if checks is set to none.
>
>If anyone else has experience splitting an OJB project across multiple
>subprojects, please let me know how you solved this problem. Currently, I
>am using a hacked version of the OJB XDoclet module with a modified
>"ensureClassRef" method that *always* sets the classref regardless of the
>check level. But really, there should be a way to load reference
>descriptors from another descriptor repository as part of the ojbdoclet
>task. Maybe something like this:
> <ojbdoclet destdir="${src.java.dir}">
> <externalDescriptorRepository>
> <fileset dir="${common.dir}">
> <include
>name="repository_user.xml" />
> </fileset>
> </externalDescriptorRepository>
>
> <fileset dir="${src.java.dir}" />
> <ojbrepository destinationFile=
>"repository_user.xml"/>
> </ojbdoclet>
>
>The descriptor repositories identified by the nested fileset element would
>have to be merged into the global repository before checking the
>constraints of the java files found in the ${src.java.dir} ...
>
>
Mhmm, reparsing existing repository-files is much more difficult than it
sounds, basically because the module has no control about the parsing
that XDoclet performs, and reparsing would mean generating XJavadoc
nodes for at least some of the nodes, to satisfy XDoclet (the core, not
the module) in some places.
One of the ideas for 1.1 btw. was to unify the models of OJB
(ClassDescriptor etc.) and of the XDoclet module which might make this
easier.
Another problem is that parts of XDoclet (the core, not the module) are
static, e.g. holding the parsed source code entities, which often
prohibits using an XDoclet module twice in the same Ant build script
(more precisely, with the same Ant classloader).
I could however see whether an option could be added that controls which
classes are written to the generated repository file. With this you
would still have to provide the source for Bar to the second task
invocation, but it would not write a class descriptor to the repository
file.
Tom
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org