BlackConnect
================================
(This file last updated July 23th, 2003 by Brad GNUberg)

This directory contains BlackConnect, a bridge allowing 
Java XPCOM components to be created and for Java to call 
XPCOM components written in other languages.

The source is divided into three main directories

   connect
      public headers. 
      ORB implementation.
      
   xpcom
      XPCOM stubs and proxy implementation
      
   java
      JAVA stubs and proxy implementation
      Java component loader


==============================================
Questions? Comments?
==============================================
Feel free to email me (Brad GNUberg) at bkn3@columbia.edu, 
call me at 1-510-938-3263 (San Francisco - Pacific Standard Time),
or even take me out for a beer!


==============================================
Status (July 22th, 2003)
==============================================
BlackConnect has been forward-ported to
Mozilla 1.4 on the Windows platform only.
Creating Java XPCOM components now works and 
can be called from JavaScript and C++, and 
calling XPCOM components from Java also works.
BlackConnect only works correctly on debug, 
non-optimized builds.  Exceptions need more 
robust testing, thread-safety seems to be correct
(I created a unit test to test for this).  
Passing null values currently does not work.  A
new Java build system has been integrated into
Mozilla's build system that makes creating
Java XPCOM components very easy; see this
document for more details.  Code has been added
to pass human-friendly error messages when XPCOM
exceptions are thrown over the BlackConnect
boundary, but needs to be tested more fully.

One significant issue is that the xpidl reference
string types (CString, DOMString, etc.) are currently not
supported.  These string types differ from the 
xpidl "string" type, which has pass-by-value
semantics rather than pass-by-reference.  Supporting
the pass-by-reference string types will probably be
very hard (due to memory allocation/deallocation issues), 
but are very important to support since 
a large amount of Mozilla's IDL depends on them.  It
is currently very hard to script Mozilla through
BlackConnect without support for these types.


==============================================
Win 32 directions  
==============================================

Requirements:

* mozilla 1.4 build tree

* JDK1.3.1_06 from Sun (may work with other versions
of the JDK but they have not been tested). 

* The BlackConnect source drop (such as blackconnect_2003_july_14.tar.gz)
  available from java.mozdev.org.

How To Build:

* make sure that your build environment is setup for Mozilla

* you must export the variable MOZ_BLACKCONNECT=1

* you must define a JDKHOME variable to the root of your JDK, 
  with no trailing slash.  This should be in /cygdrive format, such as /cygdrive/d/jdk1.3.1_06.
  While running Cygwin type export JDKHOME=/cygdrive/d/jdk1.3.1_06 or wherever your JDK is)

* add $JDKHOME/bin, $JDKHOME/jre/bin, and $JDKHOME/jre/bin/hotspot to your PATH from within Cygwin,
  as well as the dist/bin and dist/bin/components directories:
  export PATH=$PATH:$JDKHOME/bin:$JDKHOME/jre/bin:$JDKHOME/jre/bin/hotspot:/cygdrive/d/mozsrc/mozilla/dist/bin:/cygdrive/d/mozsrc/mozilla/dist/bin/components

  if your Mozilla source was in /cygdrive/d/mozsrc/mozilla (change this portion
  to point to where your own particular Mozilla source code is).

* you must add to your CLASSPATH the dist/classes directory; 
  this must be in Windows file path notation.
  for example, if your Mozilla source code was in d:\mozsrc\mozilla,
  then from within Cygwin you would type:

  export CLASSPATH="d:\mozsrc\mozilla\dist\classes"

  Make sure to have quotes on the value.

* first build the Mozilla 1.4 source _without_ the BlackConnect changes
  unzipped:

  type "./configure" and then "make" from within your top-level Mozilla directory.

* change your working directory to one level above your top-level Mozilla source
  directory.  For example, if we untarred the Mozilla 1.4 source into d:\mozsrc,
  so that we had d:\mozsrc\mozilla, we would "cd" into d:\mozsrc.  
  Now ungzip and untar the blackconnect source drop there:

  gunzip blackconnect_src_2003_07_14.tar.gz
  tar -xvf blackconnect_src_2003_07_14.tar

* change your directory to the mozilla directory:

  cd mozilla

  remove its Makefile:

  rm Makefile

  cd to the config directory:

  cd config

  remove its Makefile:

  rm Makefile
  
* type "./configure" from within your top-level Mozilla directory.  

* go into java/xpcom and type make

To not include BlackConnect in your build:

* delete the dist directory

* type:
  unset MOZ_BLACKCONNECT

* in the root Mozilla directory type:
  ./configure

  and 

  make


==============================================
Linux/Mac OS X directions  
==============================================
(Volunteers still needed to get BlackConnect
to compile on these platforms using a recent
version of Mozilla)


==============================================
How to run
==============================================

There is a sample Java component to test your build in mozilla/java/xpcom/java/test.  To build it:

* cd java/test

* make

The test component is automatically placed into dist/bin/components and loaded on mozilla
startup (or you can use regxpcom for testing)

To see if everything worked out in your build, type 'xpcshell' to run the xpcshell.
At the xpcshell prompt, type:

var test = Components.classes["@mozilla.org/blackwood/blackconnect/test/bcJavaSample;1"].createInstance(Components.interfaces.bcIJavaSample);
test.TestBlackConnect();

You should see the following printed to the command-line if you are using a debug
build (along with a tremendous amount of debugging information from the BlackConnect code):

All your BlackConnect are belong to us.

Look at the java/xpcom/java/test/bcIJavaSample.idl XPCOM interface for 
more methods you can call.

If you are building a non-debug, optimized build and want to test to see if 
everything compiled correctly, create the sample nsIFoo component below by
going into java/xpcom/sample, make it, go into dist/bin, type regxpcom, and
then start Mozilla.  Go to the JavaScript console and run the component by
following the directions below in the section titled "How to create your
own Java XPCOM component".  Note that there are currently problems with
BlackConnect working correctly in non-debug, optimized builds (see
"Known Issues" near the end of this README file).


==============================================
How to create your own Java XPCOM component
==============================================
In this example we'll be creating an example 
Java XPCOM component that implements our own
custom XPCOM interface nsIFoo.  The source code
for these examples can be found in java/xpcom/sample.

First, define your IDL for nsIFoo in the file
nsIFoo.idl:

#include "nsISupports.idl"
#include "nsIComponentManager.idl"

#pragma prefix 
[scriptable, uuid(DF9717D1-C1EF-46f6-9D04-7F50B4CF167B)]
interface nsIFoo : nsISupports
{
	void Foo1(in long l);
	void Foo2(in nsIComponentManager cm);
};

Next, create a Makefile in the same directory as 
nsIFoo.idl.  The BlackConnect system includes an
extensive Java build system to make creating Java
XPCOM components easier.  Here is the example
Makefile for our sample component:

#!make

DEPTH       = ../../..
topsrcdir   = ../../..
srcdir      = .
VPATH       = .

# Our Java XPCOM component

# The name that will be given to the JAR file holding this XPCOM component (i.e. nsJavaFoo.jar)
JAVAMODULE      = nsJavaFoo

# Any new IDL files that are defined for this Java XPCOM component
# These will be copied to dist/idl
JAVAXPIDLS      = nsIFoo.idl

# Any IDL files that your Java source-code depends on that live in dist/idl.
# You don't have to include IDL files that are referenced from your new Java IDL defined in 
# JAVAXPIDLS because xpidl will automatically import and copy these over.
# However, if your Java sources need to use other XPCOM components then they must be included
# in this variable.
JAVAIDLREQUIRES = nsIConsoleService.idl nsIConsoleMessage.idl nsIConsoleListener.idl

# Your Java sources to implement your XPCOM component.
# You shouldn't put any .java files here that are generated from IDL files
# (such as nsIFoo.java generated from nsIFoo.idl)
JAVASRCS        = nsJavaFoo.java

include $(DEPTH)/config/javarules.mk

For details on how to setup the Makefile for your own
Java XPCOM component simply look at the comments in the
sample Makefile above.  The DEPTH and topsrcdir give
the number of directories above your source-directory
to the root Mozilla source directory, including the
source directory.  For example, if your Mozilla source 
code is in /mozilla, and your Java component was 
in /mozilla/java/xpcom/sample, then DEPTH would be
../../.., or three directories to get to /mozilla.

Note: If you are planning on creating a Makefile that will
integrate with Mozilla's build system, then your makefile
will be slightly different (it will be named Makefile.in
instead of Makefile); look
at the sample in java/xpcom/java/test/Makefile.in to see the
slight differences (there are some different includes and
a few different Autoconf variables).  You will also need
to modify allmakefiles.sh in the root of your Mozilla
source directory and add your Makefile.in to this
file.

Note 2: Using a Makefile similar to the one above,
where we include config/javarules.mk, should only be done
for relatively simple BlackConnect projects.  If you plan
to integrate C++ code into your system through JNI, have a 
multi-directories project, and other sophisticated
things, then you should fully integrate with Mozilla's 
build system.  Again, see java/xpcom/java/test/Makefile.in 
for an example.

Continuing on our example, create a .jar.info file with the same name
you defined in the variable JAVAMODULE in your Makefile.
In our Makefile we defined JAVAMODULE as 'nsJavaFoo', so we
would create a file-named nsJavaFoo.jar.info in the same
directory as our Makefile.  This file provides three details
for BlackConnect, each on a seperate line:

The Class ID for this component
The Contract ID for this component
A description for this component, displayable to the user

To generate a Class ID for your component, run guidgen at
the command line and copy the number it generates to your
clipboard (but delete the little { and } characters it adds
at the beginning and ending of the GUID).  Here is a sample 
nsJavaFoo.jar.info file, with a Class ID generated from 
guidgen:

DF9717D1-C1EF-46f6-9D04-7F50B4CF167B
@mozilla.org/blackwood/blackconnect/sample/nsJavaFoo;1
A sample Java XPCOM component

Next, create a file named manifest with the following
single line:
Component-Class: nsJavaFoo

For the Component-Class value give the class that implements
your interface, not the interface name itself.

Fifth, create an implementation Java class for the
Java XPCOM interface defined in nsIFoo.  Here is
nsJavaFoo.java, an implementation of nsIFoo.java:

import org.mozilla.xpcom.*;

public class nsJavaFoo implements nsIFoo {
    public Object queryInterface(IID iid) {
        Object result;
        if ( iid.equals(nsISupports.IID)
             || iid.equals(nsIFoo.IID)) {
            result = this;
        } else {
            result = null;
        }
        return result;
    }

    public void foo1(int l) {
        System.out.println("Foo on you: " + l);
    }

    public void foo2(nsIComponentManager cm) {
	  nsIXPIDLServiceManager sm = Components.getServiceManager();
	  IID consoleServiceIID = new IID("a647f184-1dd1-11b2-a9d1-8537b201161b");
	  nsIConsoleService console = 
		(nsIConsoleService)sm.getServiceByContractID("@mozilla.org/consoleservice;1", consoleServiceIID)
										.queryInterface(consoleServiceIID);
	  // this won't print if from xpcshell, only in the JavaScript console if a debug build of Mozilla is running
	  // bkn3@columbia.edu
	  console.logStringMessage("Hello cruel console world!");
    }

	// staticly load any XPCOM classes we use in the implementation
	// of our component
    static {
      try {
		Class nsIConsoleServiceClass = 
              Class.forName("org.mozilla.xpcom.nsIConsoleService");
		InterfaceRegistry.register(nsIConsoleServiceClass);

		Class nsIConsoleMessageClass = 
              Class.forName("org.mozilla.xpcom.nsIConsoleMessage");
		InterfaceRegistry.register(nsIConsoleMessageClass);

		Class nsIConsoleListenerClass = 
              Class.forName("org.mozilla.xpcom.nsIConsoleListener");
		InterfaceRegistry.register(nsIConsoleListenerClass);
      } catch (Exception e) {
          System.out.println(e);
      }
    }

}

Notice several things about our implementation 
class.  First, we must import org.mozilla.xpcom.*,
where many of the BlackConnect classes are.  Also,
all Java stubs that are generated from the xpidl
utility are automatically placed into the Java
package org.mozilla.xpcom, so you must import this
package in order to access your generated XPCOM
IDL Java interfaces.

We also have to implement the queryInterface
method, as defined in nsISupports, but we
don't need to define the AddRef and Release
methods.

BlackConnect also transforms all method names
from C++ naming, where method names are
traditionally capitalized such as MethodOne()
or MethodTwo(), to Java naming where the
method name is not capitalized, such as 
methodOne() and methodTwo().  In our example
above to implement the Foo1() and Foo2()
methods from nsIFoo, we create methods named
foo1() and foo2() rather than Foo1() and Foo2().
The same is true if you are calling any XPCOM
objects from your Java source; simply lower-case
the first letter of the method-name.

At the end of our implementation class we
also have a static block.  Any XPCOM class that
we may use in our implementation, such as 
nsIComponentManager or nsIConsoleService, have
to be initialized in a static block somewhere
in our implementation.  This static block will
be run when the class is loaded.  For each class
used, first dynamically load a Class object by
using a String:

Class nsIConsoleServiceClass = 
              Class.forName("org.mozilla.xpcom.nsIConsoleService");

Then register it with the BlackConnect InterfaceRegistry:

InterfaceRegistry.register(nsIConsoleServiceClass);

The InterfaceRegistry builds dynamic proxies so you can
work with these classes as if they were Java classes, when
in fact they are XPCOM interfaces that might be backed
by C++ or JavaScript implementations.

You now have everything you need for your Java
XPCOM component.  In the directory with all your files
enter:

make

If everything goes correctly, a JAR file named
nsJavaFoo.jar.comp should have been created and 
copied to dist/bin/components; the nsJavaFoo.jar.info
file should also have been copied to this directory.
nsIFoo.java should have been compiled and copied to
dist/classes/org/mozilla/xpcom, and nsIFoo.idl should
be copied to dist/idl.

To test your component, type:

xpcshell

at the xpcshell prompt, type:

var foo = Components.classes["@mozilla.org/blackwood/blackconnect/sample/nsJavaFoo;1"].createInstance(Components.interfaces.nsIFoo);
foo.Foo1(44);

You should see the following printed (with a great 
deal of debugging information around it):

Foo on you: 44

To test foo2(), you must be running the actual
Mozilla browser, since foo2() uses the nsIConsoleService
component, which refers to the JavaScript console.
Quit the xpcshell command shell by pressing Cntrl-C,
and then run a BlackConnect-enabled version of
Mozilla.  Open the JavaScript console by going to
Tools > Web Development > JavaScript Console, 
and inside of it type:

var foo = Components.classes["@mozilla.org/blackwood/blackconnect/sample/nsJavaFoo;1"].createInstance(Components.interfaces.nsIFoo);

Nothing will print out after you type this line;
simply press enter, clear out the JavaScript console line, and
then enter the following:

foo.Foo2();

You should see the following printed in the console:

Hello cruel console world!


==============================================
How to call XPCOM components from Java
==============================================

Before reading this read the section
"How to create your own Java XPCOM component"
right above this because we will be referring
to information in that section.

You can only call XPCOM components from Java
from a class that is in your .jar.comp file.
What this means is that you must implement
and register a Java XPCOM component so that
you have a .jar.comp file, and then put any
other classes you may need into that file.

For example, let's say that I want to make
calls on some of the Mozilla XPCOM components
that are used for browsing.  I'll need to
create a Java XPCOM component, even if I don't
want to expose any methods on it.  Simply
create an IDL file for your Java class, such
as nsIHasNoMethods.idl, and put no methods in
this class.  Next, in your implementation
of nsIHasNoMethods.idl, which we'll call
nsHasNoMethods.java, you can make calls to XPCOM
components.  In fact, any class that you bundle
into your .jar.comp file can make calls to XPCOM
components.

To get a ComponentManager or ServiceManager to
start getting components from, call either:

nsIXPIDLServiceManager cm = Components.getServiceManager()

or 

nsIComponentManager sm = Components.getComponentManager()

Use the service manager to get access to XPCOM components
that only have one instance already created (i.e. 
services).  Use the component manager to create new
instances of a component.

Here is an example using the service manager:

nsIXPIDLServiceManager sm = Components.getServiceManager();
IID consoleServiceIID = new IID("a647f184-1dd1-11b2-a9d1-8537b201161b");
nsIConsoleService console = 
	(nsIConsoleService)sm.getServiceByContractID("@mozilla.org/consoleservice;1", consoleServiceIID)
	.queryInterface(consoleServiceIID);
// this won't print if from xpcshell, only in the JavaScript console if a debug build of Mozilla is running
console.logStringMessage("Hello cruel console world!");

Here is an example using the component manager:

nsIComponentManager cm = Components.getComponentManager();
IID 

Only XPCOM components that have included the
keyword 'scriptable' in their IDL are callable
from Java.  Also, there is currently no support
for the following IDL types:

AString, ACString, AUTF8String, DOMString

Any types that are native, or the ptr or ref types,
such as nsIDRef or nsIIDPtr, are also not currently
supported.

==============================================
Known Issues 
==============================================
* BlackConnect has serious breakage when run
  against optimized, non-debug builds; however,
  it runs fine when run against non-optimized,
  debug builds.  Can't figure out why.
* The following types are used in IDL but are
  either not currently supported by the bridge
  or haven't been tested:
	* AString (not supported)
	* ACString (not supported)
	* AUTF8String (not supported)
	* DOMString (not tested)
	* IID, CID, and ContractID ptr and ref types (not tested)
	* nsIID (not supported)
* BlackConnect does not currently build on Linux, Solaris,
  and OS X.  The Makefile.in's need to be 
  updated to get this going.
* BlackConnect probably doesn't work with
  internationalized file systems, where the component name 
  or the pathname is Unicode.
* Earlier code from Sun might not be triple licensed
  under LGPL/GPL/MPL, since it was developed when
  Mozilla was at release M4 (2001).
* Right now running an applet with a BlackConnect enabled
  build of Mozilla fails; this is because we are linking
  right to the jvm.dll and not through OJI (Open Java Interface).
* Get BlackConnect working against OJI.
* Giving a null value to a Java XPCOM component does not work
  (such as calling "JavaComponent.Foo(null);" from JavaScript on
  a Java XPCOM component. 
* For some reason, untarring a vanilla Mozilla 1.4 source distribution
  and then untarring the BlackConnect source distribution then building
  fails.  It dies because mozilla/xpinstall/src can't find nsBuildID.h, which
  should have been exported by mozilla/config/Make, but isn't for some reason.
  I spent about a day and a half trying to solve what is going on but needed
  to get this out.  The workaround is to build the Mozilla tree without 
  the BlackConnect changes in the directory, then untar BlackConnect into 
  the Mozilla tree, then build just BlackConnect.  This seems to work.

Status of these issues (7-14-2003):
  I am currently not working on fixing any of these issues,
  since I need to code other stuff right now;
  want to work on them?  Email me at bkn3@columbia.edu.


==============================================
Todo List 
==============================================
* Fix all Known Issues.
* Check the compatibility of BlackConnect against more
  JDK versions
* Make working with the component manager and service manager 
  easier from Java, including exposing IIDs as some nice constants 
  somehow rather than having to give the numeric IID.  Or maybe even
  simply revisit the Java-XPCOM API to make it radically simpler
  to work with.
* Right now we have to custom register whatever XPCOM interfaces 
  we use in our java code  in a static code block:
	Class nsIComponentManagerClass = 
        	Class.forName("org.mozilla.xpcom.nsIComponentManager");
	InterfaceRegistry.register(nsIComponentManagerClass);
  Can we somehow use a custom classloader for this so that coders
  aren't exposed to this implementation detail?
* Get java/xpcom/test working, including its makefiles.
* Put all the blackconnect files in dist/classes into 2 jars: 
  blackconnect.jar for the core blackconnect classes and 
  xpcom-support-classes.jar for all of the proxies we generated
  from the xpcom idl interfaces.
* Collapse the .jar.comp and .jar.info stuff together, so we 
  only have one file to maintain, and move the information 
  that is in .jar.info into the jar files manifest file, 
  which would be clearer anyway, such as:
  	manifest:
	xpcom-cid: 234234234234
	xpcom-contractid: @mozilla.org/foo
	xpcom-description: something foo this way comes
  Note: We might not want to do this, due to performance concerns
  with having to partially uncompress the manifest file to get
  the metadata we need.  This might be moot though since component
  registration happens during development time for optimized builds,
  when the metadata would be needed and registered.
  with having to unJAR files at startup for component registration.
* Create a better set of regression tests for everything
* Scan all open bugs for BlackConnect and see if they still
  apply:
  http://bugzilla.mozilla.org/buglist.cgi?query_format=&short_desc_type=allwordssubstr&short_desc=&product=Browser&component=Java+to+XPCOM+Bridge&version=1.0+Branch&version=1.4+Branch&version=Other+Branch&version=Trunk&long_desc_type=substring&long_desc=&bug_file_loc_type=allwordssubstr&bug_file_loc=&status_whiteboard_type=allwordssubstr&status_whiteboard=&keywords_type=allwords&keywords=&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=VERIFIED&emailassigned_to1=1&emailtype1=exact&email1=&emailassigned_to2=1&emailreporter2=1&emailqa_contact2=1&emailtype2=exact&email2=&bugidtype=include&bug_id=&votes=&changedin=&chfieldfrom=&chfieldto=Now&chfieldvalue=&cmdtype=doit&order=Reuse+same+sort+as+last+time&field0-0-0=noop&type0-0-0=noop&value0-0-0=

Status of this list (5-1-2003):
  I am currently not working on implementing any of these things,
  since I need to code other stuff right now;
  want to work on them?  Email me at bkn3@columbia.edu.


==============================================
What are all those wierd directories? 
==============================================

The BlackConnect bridge is a little 
over-modularized, making it difficult to 
understand the relationship between different
modules.  I created the following chart to
help me understand what the responsibilities
of each of the 'directories' are:

java/classes - This directory is how Java
	itself interacts with the BlackConnect
	system.  It consists of a series of Java
	classes, some that have native implementations.
	Some important classes in this directory:
		*ComponentLoader - loads a Java XPCOM JAR
		file and registers the component with the 
		InterfaceRegistry
		*InterfaceRegistry - Register classes with this
		service; it also caches reflected method objects
		*ProxyFactory - Provides a standard way to get a 
		proxy object to call on an XPCOM component
		*ProxyHandler - Uses Java's invocation handler framework
		to act as a central way to handle any interface type.
		Inside it uses Utilities.java to call the actual method
		*Utilities - Has native methods implemented in bcjavastubs.dll.
		Acts as an abstraction to do the actual XPTCall by index stuff.
		Also gives a list of interface names for a given interface ID.
		*Components - Your static starting point to get the
		Component and Service managers.  Also causes the
		blackconnectjni.dll to load and initialize.
		*Debug - A Java wrapper around Mozilla's XPCOM debug components.
	
java/src - Native implementation of Debug and Utilities.  Produces
	bcjavastubs.dll.  The C++ classes here actually implement the
	proxy and stubs and marshalling and unmarshalling on the Java
	side.

java/components - I think this gets the XPCOM component and service managers
	on startup, and sets them on a Java based XPCOM component - this
	happens through an exported dll (blackConnectInit.dll)

java/jni - Exports blackconnectjni.dll.  This dll initializes XPCOM
	(but not through an exported dll method). Provides the native 
	implementation of org.mozilla.xpcom.Components, contained in
	java/classes, which exposes a method to initialize XPCOM,
	called initXPCOM(). 

java/loader - Exports javaloader.dll.  Has an implementation of 
	nsIModule, nsIComponentLoader, and nsIFactory that can work
	with Java XPCOM components.  This dll registers itself on startup,
	adding a new "component-loader" for types of files "application/java".
	Alot of this magic happens in bcJavaComponentFactory.cpp.


==============================================
A Note to BlackConnect Developers
==============================================
This section contains information for people who
are hacking on the BlackConnect code.

java/xpcom/Makefile.in has a special make
command named "projectdist"
that helps with creating an open-source distribution
for BlackConnect, such as patch files, zipped source
files, etc.  This make command helps
in generating the files needed for the
java.mozdev.org/blackconnect site.
See the documentation in 
mozilla/java/xpcom/projectdist.mk for more information
on how to work with this directive.

IMPORTANT: If you add a new file or directory
you should check java/xpcom/projectdist.mk to see
if the "distribution" directive needs to be
updated somehow.

=================================================================
Scratchpad (Or, A Place for Random Notes to Myself, Brad Neuberg)
=================================================================
What I've done so far:

Commented out NS_INIT_REFCNT in constructors for:
*bcORBComponent.cpp
*bcXPCOMWrappers.cpp
*nsIXPIDLServiceManager.cpp
*bcXPCOMProxy.cpp
*bcXPCOMStubsAndProxies.cpp
*bcTestImpl.h
*bcJavaComponentLoader.cpp
*bcJavaStubsAndProxies.cpp

Updated allmakefiles.sh with all of our BlackConnect makefiles.

Configuration: You must set a JDKHOME variable before the java/JNI portions will compile correctly.  

Configuration: You must define a JDKHOME variable to the root of your JDK, with no trailing slash.  This should be in /cygdrive format, such as /cygdrive/d/jdk1.3.1_06

Configuration: add $JDKHOME/bin and $JDKHOME/jre/bin/hotspot to your PATH (may have to set outside of BASH in shell in Control Panel first) - maybe also jdkhome/jre/bin

ran xpidl -m java on nsISupports.idl, nsIComponentManager.idl,  nsIServiceManager.idl, nsIXPIDLServiceManager.idl, and moved their .java files over to org/mozilla/xpcom

put bcIJavaSample.java into the org/mozilla/xpcom package but within java/xpcom/java/test, as all XPCOM components are by default

We should abandon the xpidl_java.c that is in java/xpcom/java/xpidl directory and adopt the one that is in xpcom/typelib/xpidl/xpidl_java.c after it has been patched with xpidl.patch

The java/xpcom/java/xpidl directory should simply be abandoned (deleted)

Problem: Is it ok to simply convert the IDL types AString, ACString, and AUTF8String to java.lang.String types?

Design scratchsheet:
To get AStrings, ACStrings, and AUTF8String working:
	Get XPIDL compiler to convert all of these into String values (finished)
	Figure out where responsibility lies for the marshalling and unmarshalling of
		these string classes in the correct way

Todo: implement an OpaqueValue class just in case.

Converted the XPCOM connect tests to use Netscape Assertions rather than printfs (java/xpcom/xpcom/tests)

Todo: make sure we can handle DOMString type and nsIID type

Todo: Make sure weak references work

Todo: Make sure those wierd IID ptr and ref types work

Todo: Make sure a single make from the root of the blackconnect directory will completely and correctly create blackconnect.

Changed bcJavaComponentLoader to not use the nsIRegistry and instead use the nsIComponentLoaderManager.

Todo: Surround printf's with a DEBUG macro or something (or whatever they have for different levels of log messages)

Configuration: I had to add where jvm.dll was to my PATH (it should be in $JDKHOME/jre/bin/hotspot or something like that)

Configuration: Must add to CLASSPATH where all of our core Java XPCOM classes are (they should be in dist/classes).

Configuration: Must add to PATH the components directory (i.e. dist/bin/components) so that our JNI stuff can load the DLLs we need

Known Limitation: this will probably not work with internationalized file systems, where the component name or pathname is unicode.

Todo: Remove any printfs that had numbers in them for debugging (i.e. foo 1, foo 2, etc.)

Todo: get release form from igor to triple license the code?

Todo: Make sure blackconnect works not only on a debug build but on a release build as well where we have to regxpcom our components

Todo: Make sure BlackConnect works from C++ (i.e. calling a Java XPCOM component)

Todo: Check JDK compatibility.

Todo: See if we can use the XPCOM proxy service from our Java component to some JavaScript component.

Todo: See if calling a Java XPCOM component from a JavaScript XPCOM component works, and vice versa.

Todo: Right now running an applet with blackconnect enabled fails.  Solve this.

Todo: Make working with the component manager and service manager easier from Java, including exposing IIDs as some nice constants somehow rather than having to give the numeric IID.

Todo: Make sure exceptions work from both directions.

Todo: Make sure null values work for both basic types, for native pointers, and for XPCOM interface in and out values from both directions.

Todo: Right now we have to custom register whatever XPCOM interfaces we use in our java code in a static code block:
	Class nsIComponentManagerClass = 
        	Class.forName("org.mozilla.xpcom.nsIComponentManager");
	InterfaceRegistry.register(nsIComponentManagerClass);
Can we somehow use a custom classloader for this?

For testing: var sample = Components.classes["@mozilla.org/blackconnect/test/bcJavaSample;1"].createInstance(Components.interfaces.bcIJavaSample);

Todo: Resolve use of System.out.println's with Debug.outs.

Todo: Figure out why servicemanager.getServiceByContractID isn't casting what it returns
to the IID it is given.  We are forced to do a seperate QueryInterface on what it returns
to get what we want.

FAQ: Q: I'm getting an error when I try to (cast) my nsISupports to something else.  What's up? A: Remember, you need to use QueryInterface instead!!!

Todo: Break up diffs into seperate, easily reviewable pieces (maybe Makefiles.diff, Tests.diff, StarConnect.diff, XPCOMConnect.diff, and JavaConnect.diff?)

Todo: Figure out why we get those files with the strange string of characters in java/xpcom/java/loader (they look like internationalized unicode strings or something).

Todo: Get java/xpcom/test working, including its makefiles.

Todo: File bug report that clobber isn't deleting .ilk files, such as in java/xpcom/connect/xpcom

Todo: Put all the blackconnect files in dist/classes into 2 jars: blackconnect.jar for the core blackconnect classes and xpcom-support-classes.jar for all of the proxies we generated from the xpcom idl interfaces.

Todo: Convert BlackConnect to use OJI so that applets will work and test with simulateneously running an applet.

Changed allmakefiles.sh and Makefile.in in the root directory for our new directive, MOZ_BLACKCONNECT, on whether to build blackconnect

Configuration: To build BlackConnect: 
	export MOZ_BLACKCONNECT=1
	./configure

	To unbuild:
	unset MOZ_BLACKCONNECT
	./configure

Todo: Change our bcJavaSample contract ID to be @mozilla.org/blackwood/blackconnect/test/bcJavaSample;1

Todo: Collapse the .jar.comp and .jar.info stuff together, so we only have one file to maintain, and move the information that is in .jar.info into the jar files manifest file, which would be clearer anyway, such as:
manifest:
xpcom-cid: 234234234234
xpcom-contractid: @mozilla.org/foo
xpcom-description: something foo this way comes

Todo: Create a set of regression tests for everything

Todo: Add a TestBlackConnect() method onto our Java XPCOM component for users to easily see if the build worked.

Question: Added *.ilk to be clobbered; is this ok?

Created a Java build system integrated into the Mozilla build system

Created new directory java/xpcom/sample to hold a sample Java XPCOM component

Todo: Figure out why any class files with a dollar sign in them aren't clobbered.

Broke the java build system rules into a seperate file named javarules.mk, and included these
into rules.mk.  This is so Makefiles outside of the Mozilla build system can easily
use the Java rules

Todo: Null values don't seem to be working; test from both directions.

Todo: The .jar.comp file isn't remade if the manifest file has been changed.  Known problem.

Todo: I think there are all sorts of subtle dependency problems, where things that should
be rebuilt aren't even if dates have changed on files.  Things work correctly if you do a make clobber before a make, but probably not otherwise.

Todo: Having more than one IDL file for JAVAIDLREQUIRES isn't calling xpidl on each of the
idl files; instead, it is only called on the first one.

Todo: For some reason, returning strings on a debug build _works_ but on an optimized build it _doesn't_ (I get a null value).  What the fuck?

Todo: Test everything against an optimized build, since it seems to really run differently.

Todo: Make sure objects as return values work when objects are both Java and non-java xpcom objects.

Todo: Make sure the sample component section in the readme is correct after we finish fooling around with nsFoo.

Added org.mozilla.xpcom.XPCOMException class in java/xpcom/java/classes

var test = Components.classes["@mozilla.org/blackwood/blackconnect/sample/nsJavaFoo;1"].createInstance(Components.interfaces.nsIFoo);

Todo: Java classes get compiled in java/xpcom/java/classes even if they haven't changed; does this also affect if we use the Java Build system for Java XPCOM components support classes?

Todo: Somehow create a mapping between result codes and strings to return a "nice" XPCOMException message.

Added mappings between result codes and nice exception messages - added xpcom_exceptions.msg

Todo: figure out who does the destruction of the exception Result Map

Todo: There is probably memory leaking all over the place

Todo: Ensure actually using the component manager works

Todo: Add some real examples of using the component managers and service managers to the README

Todo: Add --enable-blackconnect and --disable-blackconnect flags

Todo: if an exception is generated inside the Java, we can also maybe somehow generate an nsIException, which has all sorts of nice extra information where we can put the line number, java file, etc.

Todo: Add some of our new testing directories, such as thread-test and sample, to the make Makefile.in but commented out
