Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Opentools - sys.Author & classpath trouble

2 views
Skip to first unread message

alexvh

unread,
Oct 7, 2005, 12:40:57 PM10/7/05
to
Hello everybody,
I just started developing my first opentools. This works fine, except for a
few strange problems I cannot solve. To briefly explain what I'm trying to
do : I'm adding several wizards to the Object Gallery that will generate
code based on templates. I'm using JBuilder2006 BTW, and I'm not a very
experienced JBuilder user.

1) I would like to add an Author automatically. Now, what I've found on the
internet is that you set this and several other properties using Project -
Project Properties - General and then there's a grid called Class Javadoc
fields. This grid contains title, description, company, @author and others.
I've given values to all of them.

In my code, I use :

jbproject.getProperty("sys", "Author", ""); // jbproject is a JBProject
instance

This, however, always gives me the default value I specify (""). What is
even more strange : I've asked for a list of all properties, and stepped
through them all using the debugger and *every single one* of the properties
(title, description, ...) is shown using this technique. There is a
sys.Authorlabel property which contains @author but then it jumps right to
the next property! There simply is no sys.Author property in my object,
allthough there is a value specified for it.

Anyone knows of another way to get the Author's name? Or knows what I'm
doing wrong?

2) second problem seems to be a classpath problem. Using my templates, I
add classes to my project. There is one wizard that must look for
(autogenerated) classes that implement a specific interface, and generate
extra code for those classes. I can locate the classes I want in my project
without a problem. I use reflection to see whether a class implements the
interface I want or not.

I'm debugging my opentools using the well known technique of starting
another jbuilder instance (see e.g.
http://www.devdaily.com/blog/Content/2/3/417/). When I debug my code (=run
in debug mode), it works fine. I look up my classes using Class.forName,
and they are found. When I deploy my opentool and run it without debug, I
get classNotFoundExceptions all the time using the exact same project with
the same classes, without changing my code.

I hope this makes some sense ;-) In short, I think there's a difference in
classpath setting between the debug and non-debug mode for classes that are
in my project classpath (all classes are in the classes directory of my
project).

Any ideas here, because I really have no clue how to solve this one.

Phew, not sure if anyone knows what the hell I'm talking about, but please
let me know if you need more information.

Thanks a lot,
Regards
alex.


Bill Joy

unread,
Oct 7, 2005, 1:45:14 PM10/7/05
to
The author name is kept in the .jpx.local file so that all team members can
share the same .jpx file:

String author = jbproject.getAutoProperty("sys", "Author");

Your "well known technique" for debugging an OpenTool is not the best
approach. It is much easier to just create an OpenTool run/debug
configuration (choose "OpenTool" in the "Type" combobox instead of
"Application").

How are you deploying your tool? You should be creating a JAR and placing
it in the \jbuilder\lib\ext directory. If you don't do that, then you will
have to modify the \jbuilder\bin\jbuilder.config file (and add either an
"addjars" command to point at a directory containing your JAR, or an
"addpath" command to point at the root directory of where your class files
reside).


"alexvh" <su...@mail.com> wrote in message
news:4346a487$1...@newsgroups.borland.com...

alexvh

unread,
Oct 7, 2005, 2:16:54 PM10/7/05
to
Thanks Bill,
I'll try the getAutoProperty on Monday and thanks for the tip on the
debugging configuration !

I am deploying my tool like that. This is my directory structure :
// the main wizard classes
project_home\src\com\company\opentools\wizard\*.java
project_home\classes\com\company\opentools\wizard\*.class

// some utility classes
project_home\src\com\company\opentools\util\*.java
project_home\classes\com\company\opentools\util\*.class

To deploy, I open a command prompt in the project_home directory and type
jar -cfm myjarfile.jar manifest.file -C classes com.
I copy myjarfile.jar to Jbuilder home\lib\ext. I am aware of the technique
you describe (using addpath and addjars), I found this on the internet as a
technique to temporarily deploy an opentool without actually creating a jar
for it and putting it in the lib\ext directory. Is that rigth?

If it helps, the classes I'm generating with my wizards, are in a completely
different package structure. This is because I'm trying to develop these
wizards as standalone tools. The generated classes are always in a fixed
package structure.

So basically, I deploy my opentools and generate, in my opentools project
(=the project I use to develop the opentools, not the project I actually
need the wizards for), a first class in a package
my.completely.different.package.MyClass using a first wizard. This class is
added to the project in directory src\my\completely\different\package (I
automatically create the necessary directory structure if necessary) and it
compiles ok, so there is a .class file in the corresponding
classes\my\completely\different\package directory. Then I start another
wizard, which will look for classes in the my.completely.different.package
package that implement a specific interface.

What I see now is that, when debugging my project (using the technique I
described earlier), the project_home\classes directory is somehow in my
classpath, and a
Class.forName(my.completely.different.package.mySecondGeneratedClass) works.
When the tool is not being debugged, this statement throws a
classNotFoundException.

I hope this helps,
and thanks again, I appreciate it,

Regards,
alex.


"Bill Joy" <wc...@pacbell.net> schreef in bericht
news:4346b39e$1...@newsgroups.borland.com...

Bill Joy

unread,
Oct 7, 2005, 4:09:17 PM10/7/05
to
If you use the OpenTool run/debug configuration, you do not need to create a
JAR to run or debug your OpenTool. (When you use that configuration to
run/debug an OpenTool, a copy of jbuilder.config is created with your
project classpath appended to it, and that is used to launch the second copy
of JBuilder.)

When you are ready to deploy and so create a JAR file, run JBuilder with
the -verbose command line option to see if recognizes your JAR (which should
be in \jbuilder\lib\ext) as containing an OpenTool (meaning it has a good
manifest), and that your OpenTool is being loaded and initialized
successfully.

I am not sure I understand what you are talking about with regard to the
classes that your wizard is generating. Are the classes being added to the
currently open project? Where is this call to Class.forName() being
executed from?


"alexvh" <su...@mail.com> wrote in message

news:4346bb04$1...@newsgroups.borland.com...


> Thanks Bill,
> I'll try the getAutoProperty on Monday and thanks for the tip on the
> debugging configuration !
>
> I am deploying my tool like that. This is my directory structure :
> // the main wizard classes
> project_home\src\com\company\opentools\wizard\*.java
> project_home\classes\com\company\opentools\wizard\*.class

> profi

alexvh

unread,
Oct 7, 2005, 5:21:28 PM10/7/05
to
Hi,
I do use the -verbose -nosplash command line options, and there is a message
telling me the opentools initialize succesfully. And, my wizards are
visible in the Object Gallery, so they seem to initalize OK.

About the classes that are generated : I've created a project to develop my
wizards. Right now I'm adding my generated classes in my opentools project
(the currently open project) The code of my wizard, in my wizard project,
contains the call to Class.forName().

The thing is, my wizards are in a package structure A, and the classes I'm
generating are for a project that is about to start next month, and these
generated classes will be in package structure B (this package structure is
fixed).

So my wizard code generates classes that are in a different package than the
package of my wizard code, and some of my wizards want to dynamically
examine (using reflection) the classes some of my other wizards have
created.

I hope this helps and thanks again.
Sorry if it's not clear

Regards,
Alex.

"Bill Joy" <wc...@pacbell.net> schreef in bericht

news:4346d561$1...@newsgroups.borland.com...

Bill Joy

unread,
Oct 8, 2005, 2:23:16 AM10/8/05
to
So -- within a running JBuilder (modified by your OpenTool) you are
generating sources from a wizard, compiling them into a directory which is
part of the JBuilder classpath, and then trying to load those classes via
JBuilder's class loader?

I think you should be using the Class.forName() method which allows you to
provide your own ClassLoader instance. Otherwise you will probably run into
issues with caching and perhaps other behavior built into JBuilder that
probably is causing the behavior you are describing.


"alexvh" <su...@mail.com> wrote in message

news:4346e644$1...@newsgroups.borland.com...

alexvh

unread,
Oct 9, 2005, 5:51:19 AM10/9/05
to
First of all, I tested the getAutoProperty, and this works perfectly.
Thanks for that Bill!

My classpath problem is still the same though. It's getting a bit annoying
... This is what I've tried, following the suggestion Bill made.

In a wizard page, I'm trying to fill a combobox with all classes that
implement a certain interface, this is the code I'm using :

private void fillCombo() {
Node[] nodes = project.getPackageNodes(PACKAGE_NAME);
String cl = null;
String name = null;
for (int i = 0; i < nodes.length; i++) {
name = nodes[i].getDisplayName();
if (name.endsWith(".java")) {
cl = PACKAGE_NAME + "." +
name.substring(0, name.indexOf(".java"));
if (isCorrectClass(cl)) {
comboDAOInterface.addItem(cl);
}
}
}
}

If this is horrible code and it could be written much better, please do not
hesitate to correct me ;-)

the isCorrectClass method will check to see if the class we're looking at
now implements a certain interface :

private boolean isCorrectClass(String cl) {
try {
URL[] urls = new URL[1];
try {
urls[0] = project.getPaths().getOutPath().toURL();
} catch (MalformedURLException ex1) {
if (PrimeTime.isVerbose()) {
System.out.println(ex1.getMessage());
ex1.printStackTrace();
}
}
URLClassLoader loader = new URLClassLoader(urls);
Class c = loader.loadClass(cl);
Class[] interfaces = c.getInterfaces();
String DAOString = PACKAGE_NAME + ".DAO";
for (int i = 0; i < interfaces.length; i++) {
if (interfaces[i].getName().equals(DAOString)) {
return true;
}
}
} catch (ClassNotFoundException ex) {
if (PrimeTime.isVerbose()) {
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
return false;
}

So what I'm doing here is getting the outpath URL (which is the classes
directory underneath the project root directory) and using this URL to
explicitly set a separate classloader. PACKAGE_NAME is a String constant
and points to an existing package. This code works fine when I debug my
opentools project, and it doesn't work at runtime (NullPointerException).

I've doublechecked : the project_root\classes\ directory contains all
necessary subdirectories for the package, and the *.class files are there.
Specifically, PACKAGE_NAME is com.gov.min.da,
project_root\classes\com\gov\min\da exists and contains the *.class files I
want to examine. Yet I cannot examine these classes using reflection.

I might be overlooking something really obvious, but I'm really not seeing
it. It's really frustrating to step through your code and seeing that it
does what it's supposed to do, but at runtime it does not work.

Thanks to anyone who can offer some help,
Regards,
Alex.

"Bill Joy" <wc...@pacbell.net> schreef in bericht

news:4347...@newsgroups.borland.com...

Bill Joy

unread,
Oct 9, 2005, 2:52:15 PM10/9/05
to
So where is this NullPointerException coming from?

When you generate the classes, does the Project pane automatically update to
show the new package when it is generated?

Note that the OTAPI calls in the code posted uses VFS (virtual file system)
calls. When you check that the directories actually do exist, are you using
the Files browser within in JBuilder (which uses VFS), or are you using some
other application?

My guess is that you are generating the directories and classes using
java.io.File and so not invalidating the caches kept internally by JBuilder.
A workaround is to call one of the VFS.checkCaches() methods, or in your
case it would probably be better to just call JBProject.refresh() since you
are adding to the source path.


"alexvh" <su...@mail.com> wrote in message

news:4348e77c$1...@newsgroups.borland.com...

alexvh

unread,
Oct 10, 2005, 11:41:10 AM10/10/05
to
Hello everybody,
for future reference, I've been able to solve my classpath problem using
JBProject.getClassLoader. This gives you a ClassLoader, use the loadClass
method to load a Class.

Thanks for all your help Bill.

Regards,
Alex.

"Bill Joy" <wc...@pacbell.net> schreef in bericht

news:4349664d$1...@newsgroups.borland.com...

0 new messages