FAQ on OpenOffice UDK


Hey, the OpenOffice component technology is great. How do I contribute?

Great, you're always welcome. To find some ideas on where to help please browse the open task list. If you've got questions about any of these tasks don't hesitate to ask them. Please post them to the dev@udk.openoffice.org mailing list.

Does UNO depend on OpenOffice?

In the near future, there will be an Office Development Kit available for download beside the openoffice-setup-set. This development kit contains all files (include-files, libraries, tools, etc.) that are necessary to build components. The development kit will also contain samples. These samples are built with makefiles, that only require gnumake (not the whole openoffice build environment). These makefiles can be used as a template to integrate the build of your UNO-components into your build environment.

Is UNO analogous to MS COM?

Yes, UNO can be seen as an component model completely independent from the office itself. It is in direct competition to COM. You can find a feature list here.

What is the ODK?

The Office Development Kit (ODK) extends the UDK with additional documentation, API's (more IDL's), and examples. The UDK is a subset of the ODK. If you want to extend the OpenOffice, or write solutions with OpenOffice, the ODK fits your needs. The UDK is a standalone object model, which can be used without OpenOffice. The UDK will be the main target of integration discussions with Gnome and XPCOM, for achieving the long term goal of having only one Open Source Object Model. In the future, it should be possible to write components which depend on the ODK and components which are independent from OpenOffice.

The Office Development Kit shall enable software engineers to develop components for OpenOffice without the need of the bulky OpenOffice build environment. Thus, the ODK shall include the binaries of the base libraries (+import libraries), C++ header files, all idl-files, .jar files, and development tools (code generators, tools to register components, etc.) The ODK, additionally, includes some source examples and makefiles, that only require gnumake + C++-compiler, you can take the makefiles, as an example, to integrate them into your build environment. The development kit will be provided in the future alongside every OpenOffice build and will be available as an seperate download.

Why didn't you use Java or CORBA as middleware?

We wanted a middleware which can be used for components with a fine granularity, at least, in-process. If you use different UNO components in the same language than there is no overhead (e.g., in C++ a call is only a virtual method call). Unfortunately, CORBA has no in-process specification of interfaces and structures. The only way to communicate is through the IIOP protocol. The overhead is too high for in-process communication. And we wanted to be programming language independent: let UNO be a mediator between different languages like Java, C++, C and other languages. This isn't the goal of CORBA. Another goal of UNO is to be the mediator between different object models like COM/DCOM, CORBA, Java, and XPCOM which surely isn't a goal of other object models.

What are the differences between UNO and CORBA?

UNO does not generate stub code. We did this in the former UNO2 implementation. One problem was, that the generated stub code was quite a heavy load (about 12 MB at former times, even though the API had less types as compared to now!). With UNO3 (the current version), we decided to generically call implementations, without having generated stub code, just by providing bridging code that knows the specific compiler that compiled the implementation. The only thing that is generated for C++, besides the pure virtual classes, are the getCppuType() functions to reflect types. The full type description is read at runtime from a binary storage. This approach has the advantage that on increasing numbers of types, less space is consumed. To see more the differences between UNO and CORBA, please have a look on the following comparison.

What are the differences between UNO IDL and CORBA IDL?

UNO IDL has:

Can I use OpenOffice components as JavaBeans?

Yes, the OpenOffice bean (OOBean) project enables the use of OpenOffice components in Java applications. Please visit http://whiteboard.openoffice.org/OOBean/index.html for informations, source code, or binary downloads. The OO Bean features

The project is just starting, so please be aware of bugs, incomplete documentation, install problems, etc. We invite all people with interest in OpenOffice and Java to contribute to this project, or just use the bean in their Java application.

Can you give me some example code?

C++ examples
Where What
udk/remotebridges/examples/officeclient.cxx The example shows how to build up an interprocess bridge to an OpenOffice document. Please, remember that there are no differences if you write a component for Windows or Linux.
udk/product/examples/ More examples.

HTML documentation
Where What
http://udk.openoffice.org/cpp/man/tutorial/remotedemo.html Remote demo tutorial
http://udk.openoffice.org/cpp/man/component_tutorial.html Component writing in UNO space
http://udk.openoffice.org/cpp/man/tutorial/unointro.html C++ specific guide to UNO
http://udk.openoffice.org/common/man/concept/unointro.html Language independent guide to UNO

We lack a good document on how to start developing using Java. You should have a look at the source, directly, and there are some examples in the jurt project, which you can check out using

  $ cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs co oo/udk/jurt
You'll find some examples in the source code demo-tree:

Java examples
Where What
jurt/demo/com/sun/star/demo/TestOffice.java Starts up an interprocess bridge and creates several documents in the office
jurt/demo/com/sun/star/comp/demo/ Here some sample code can be found on how to setup a JavaComponent. The sample can be registered with an office and thus runs within the same process as the office

We also suggest having a look at the sun-developer-connection (http://soldc.sun.com/staroffice), when you click on Download SDK, you can download the StarOffice Programmers Tutorial. It contains some examples on certain API-topics. Please use the dev@api.openoffice.org mailing list for asking highlevel office api questions.

How do I generate C++ type definitions?

  1. create .idl files describing the interface
  2. generate .urd file using unoidl
  3. merge the new type(s) into the system registry with regmerge
  4. create the C++ types using cppumaker (for java: use javamaker)
  5. for java: compile the generated interfaces and add them to your CLASSPATH

What's the purpose of regcomp?

The unoidl converts the IDL description into a binary type library format; this type information is needed for every IDL type at runtime. The generated output file of unoidl contains only the type information of the specified IDL file. It does not contain the complete type descriptions of all types. So, it is necessary to install the new types in the type library applicat.rdb using regmerge. If somebody has developed a UNO component, he must support/export some administration functions (e.g., component_writeInfo). In the component_writeInfo function the developer gives some information about the supported services and the implementation name. This information is later used by the service manager to instantiate the component. So, if you developed your own component, you must install your component to the runtime. This could be done with regcomp. regcomp reads the component_writeInfo function and does some administration work with the contained information. For example, all supported services of the component are inserted in a global SERVICES section, which is used by the service manager. In this section a relation between the service name and the implementation name is established. Under the reserved area IMPLEMENTATIONS you'll find the appropriate section for your own component, which is equal to the key defined in the component_writeInfo function. Please have a look at the installed applicat.rdb in your office directory:

  $ regview applicat.rdb /SERVICES
  $ regview applicat.rdb /SERVICES/<service_name>
  $ regview applicat.rdb /IMPLEMENTATIONS
  $ regview applicat.rdb /IMPLEMENTATIONS/<implementation_name> 
So regcomp is always needed if you want to install a new component. regmerge is needed to install new types in the type library.

Where is the OpenOffice API?

Please visit the http://api.openoffice.org project site.

How do I test my components?

If you develop a new component it'll end up in a shared library or dynamic link library (DLL). The DLL will be loaded on demand if the implemented service is requested. To make the component visible and usable in the OpenOffice, you'll have to register your service as a external component. To achieve this you'll need to follow these steps:

  1. copy your DLL into the .../program directory
  2. copy the tool regcomp into the .../program directory. You will find this tool in the UDK module cpputools
  3. use the regcomp tool
      $ regcomp -register -r applicat.rdb -c foo.dll
  4. If you did develop your own interfaces and other new types, then you have to register these new types in the UNO type library. For doing that you need the tool regmerge which you find in the UDK module registry. The unoidl tool generated a foo.urd file which contains the new types. You'll find this file in the output directory of your component.
  5. use the regmerge tool
      $ regmerge applicat.rdb /UCR foo.urd
    All type descriptions of IDL types are stored in the registry under the reserved key UCR (UNO core reflection)
  6. After registration of the component and the new types you are able to instantiate your service via the service manager.
A very easy and fast way to instantiate a new service is by using basic. Start a new basic script and type in the following code:
       Sub Main
         s = createUnoService("YourSerivceName")
         msgbox(s.dbg_supportedinterfaces)
       End Sub
If the instantiation is successful, the message box will show all supported interfaces of the object.

More information can be found in the README files in the directory http://www.openoffice.org/source/browse/udk/product/examples/.

How many bridges exist?

Currently there exist 4 bridges: the C++ bridge, the Java bridge, the UNO Remote Protocol (URP) bridge, and the IIOP bridge.

When is a bridge involved?

If you develop your components in C++, remember that for in process calling of components compiled by the same compiler, there is no need to bridge any interface. The component loader recognizes this fact and uses the implemented C++ interface directly. But if you use scripting (e.g., basic) to call a Java component or to do remote UNO to some other process, bridging is indeed involved.

How do I specify default values for structs?

It is not possible to specify default values for structs because these defaults cannot be used in other object models (e.g., CORBA). It is also impossible to emulate default values for member variables by modifying the unoidl-generated default constructors for structs. The default constructors set enums to the first enmum value, numbers to 0, and the other types use their default constructors. The generated inline default constructor can be found in the .hpp file. The constructor sets the members to known initial values only.

Hey, my component just dumps core. What's going wrong?

Since it's hard to tell from a stack trace only, what is going wrong, please send as much information as possible. If you're lucky, you're the writer of the service and you can send the component implementation code and the code which instantiates the object as well. If you are not the component developer then you're forced to contact the component developer.

Why is it so annoying to write a compiler version dependent C++ bridge?

The goal behind UNO is to provide the simplest language binding for the UNO component writer and user, the reduction of generated code, and a maximum of execution speed. With the current technique, the goals are reached. For example, in C++ there is no call overhead, because a C++ to C++ call is only a virtual method call. There is no compile time code generation, it is done by the bridge on the fly. The UNO C++ language binding is smarter than all other (CORBA, COM) bindings. On the other hand, writing a C++ bridge is a hard thing to do, but this has to be done only once for each compiler, operating system, and processor. There are simpler ways to achieve language bindings, but they aren't better ways. A bridge from cpp to uno is very compiler and abi dependent, and at first glance, it seems that it isn't portable at all. But it must be noted that the bridge code is pretty similar for most compilers. The main differences are the generated vtables, performing C++ virtual calls, and handling exceptions.

How do I implement a C++ bridge for a RISC cpu?

On RICS machines parameters to functions are passed in registers, whereas, the C++ bridge code manipulates a stack between the C++ layout and the required uno layout. For an example of how this is solved, please see the sunpro5 solaris sparc bridge. Registers are pushed right to stack (extending non-register parameters on the stack [if more than 6]).

Which PropertyValue should I use when loading an existing document?

A document is always opened through a loader with an empty property argument

    PropertyValue [] szEmptyArgs = new PropertyValue [0];
    String doc = "private:factory/swriter";
    aDoc = oCLoader.loadComponentFromURL(doc, "_blank", 0, szEmptyArgs ); 
Using these arguments, you can force OpenOffice to use a certain filter, open the document read-only, and set a password for password protected documents. The csv-filter for spreadsheet documents has some additional options here, which are the same as stored for the picklist in the soffice.ini/sofficerc when entered using the UI.

How do I open an existing document and then save it into HTML format?

Here's some sample code for that:

   PropertyValue [] mypv = new PropertyValue[1];
   mypv[0] = new PropertyValue();
   mypv[0].Name = new String("FilterName");
   mypv[0].Value = new String("scalc: Text - txt");
   mypv[0].Handle = -1;
   mypv[0].State = PropertyState.DEFAULT_VALUE;
   aStore.storeAsURL(doc, mypv);  //aStore is a XStorable object, and doc is url string
 

How do I save a OpenOffice document as XML?

Here's some sample code for that:

  sub SaveXML
    dim mProps(0) as new com.sun.star.beans.PropertyValue
    mProps(0).Name = "FilterName"
    'This works with 614
    mProps(0).Value = "swriter: StarOffice XML (Writer)" 
    oDesk = createUNOService("com.sun.star.frame.Desktop")
    'For some reason, ActiveComponent no longer works:
    oComponent = oDesk.CurrentComponent()
    oComponent.storeAsUrl("file:///C|/Tmp/startemp.xml",_
      mProps())
  end sub 

Should I always use queryInterface?

You don't need to call queryInterface directly. A more comfortable way is to use a special reference constructor for this. Instead of

 	::com::sun::star::uno::Any x = xI->queryInterface(
 	    ::getCppuType((const ::com::sun::star::uno::Reference< 
 			   ::com::sun::star::i18n::XTransliteration>*)0));
 	x >>= transRef;  
you should use:
 	transRef = Reference< XTransliteration >( xI, UNO_QUERY );
 

What does cannot dump type 'com/star/uno/RuntimeException' mean?

First, make sure that you followed the FAQ entry 'How do I generate C++ type definitions?'. That means: you created a .idl file that "describes" or "defines" the component. You use the unoidl tool to compile the idl file. Run the cppumaker on the resulting .urd file. The cppumaker generates a C++ representation for idl types and it works on a typelibrary which is generated by the unoidl. If you followed these steps and get the error: cppumaker ERROR: cannot dump type 'com/star/uno/RuntimeException', you must integrate your new type into the system type library because the type information is needed at runtime and also for generating the C++ code. For doing that, the easiest way is to merge your 'XXX.urd' files into the system type library. The system type library is called applicat.rdb and can be found in the program directory. To merge the type library, you must use the tool regmerge which you should find in the build environment. All type information in the applicat.rdb are saved under a reserved area 'UCR'. You must merge your own types also in this reserved area. Using regmerge:

  $ regmerge applicat.rdb /UCR yourtypes.urd
There exists another nice tool to view the contents of a registry file (= type library):
  $ regview applicat.rdb /UCR/com/sun/star/uno
This shows all types of the module com.sun.star.uno or
  $ regview  applicat.rdb /UCR/com/sun/star/uno/XInterface
shows the type information of com.sun.star.uno.XInterface Additional info about generating code: The cppumaker needs all type information because the cppumaker generates the specified type and all the dependencies. The depended types will be generated recursive, so that you get all necessary C++ type declarations you need to build your component.

You now have to use the applicat.rdb, that (after the regmerge) contains all types (the one that comes with the office and your new one). Note that the regmerge command only modifies the first file, the others are opened readonly.

You should now check with regview, that the regmerge really worked and that it now contains your new type. For example:

  $ regview applicat.rdb /UCR/com/sun/star/uno/RuntimeException  
should give output about the normal RuntimeException.
  $ regview applicat.rdb /UCR/your/new/types 
should give output about your new type (of course replace your/new/types with the module and typename of the new type in idl).

Then the following command should generate C++ headers below your current working directory:

  $ cppumaker -O. -Tyour/new/types -BUCR applicat.rdb 
If this doesn't work, at least the following command should work:
  $ cppumaker -O. -Tcom/sun/star/uno/RuntimeException -BUCR applicat.rdb 

What does symbol "component_getImplementationEnvironment" could not be found mean?

If you try to register your DLL with regcomp like this:

  $ regcomp -register -r applicat.rdb -c foo.dll
and get the following error:
register component "foo.dll" in registry "applicat.rdb" failed!
ERROR: component could not be registered: symbol "component_getImplementationEnvironment" 
could not be found in "foo.dll"
Make sure that you defined the function outside any classes in a .cxx file like this:
extern "C" 
void SAL_CALL component_getImplementationEnvironment( 
                 const sal_Char ** ppEnvTypeName, 
                 uno_Environment ** ppEnv ) 
{ 
        *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
If you are not using a module definition file (DEF file), then you can use a SAL_DLLEXPORT macro in front of your function definition, which expands to __declspec(dllexport). On Win32 platforms check your exports using
  $ dumpbin /EXPORTS foo.dll
If this still doesn't work while registering your DLL, make sure that your path is correct and that all libraries foo.dll is linked against are accessible via your path. On Win32 platforms you can use a tool which is delivered with Developer Studio 6. It's called depend and shows library imports and missing libraries (marked red). If this still doesn't help you should debug the function writeRegistryInfo() of the shared library component loader. The loader is located in the CVS module stoc which checks out the direcory oo/udk/stoc. Inside the stoc directory the loader is built in the directory source/loader. The built library is called cpld.dll.

How do I unmerge what I added to type library with regmerge?

regmerge overwrites existing keys. However, a tool to delete existing keys would be nice to have, but there currently is none.

Where do I find service descriptions in the type library?

Service descriptions are not stored in the type library because reflective information about services aren't needed at runtime. A service description exists only for modelling purposes.

You can start the IDL compiler with a special option ( -C ) to generate a type library including service descriptions and comments, it is not used in a normal office build, as it approximately doubles the file size.

How do I create a unique uik number?

Some people do it by just copying an existing one and modifying it a little. This is, of course, disapproved of, but it works for now. We currently don't have our own tool, but you can use the guidgen.exe that comes with the microsoft compiler.

However, the guids are currently not used. They are there for historical reasons (the former UNO component model needed it) and we left it in for a future, maybe, UNO-COM bridge, which would require unique identifiers.

How can I configure the office to be started in listening mode ?

There are two ways.
  1. Start the office with an additional parameter :

    soffice -accept=socket,host=0,port=2002;urp;StarOffice.ServiceManager

    ( Please ensure to quote the ; on a unix shell ).

  2. Place the same string without '-accept=' into a configuration file. You can edit the file

    <office-install>/share/config/registry/instance/org/openoffice/Setup.xml

    and replace the tag

    <ooSetupConnectionURL cfg:type="string"/>

    with <ooSetupConnectionURL cfg:type="string">socket,host=0,port=2002;urp;StarOffice.ServiceManager</ooSetupConnectionURL>

    Note that this change has effect on the whole network installation, which can easily become a very serious security problem. Please also note, that using the host=0 phrase will make the office listen on every network interface, in case you only want to script your office from the same machine, it is definitly better to replace the 0 with localhost.

    If you want to configure it only for a certain user (in a network installation), you need to do the modification into the user dependent configuration directory at the same place.

How do I start the TestOffice.java?

As parameters, please use, for example: uno:socket,host=localhost,port=2002;urp;StarOffice.NamingService

How do I remotely connect to an OpenOffice running on a different machine?

When connecting to an OpenOffice you supply an Uno URL, which allows to locate a named Uno object in a different process. A Uno URL consists of four parts:

Those four parts are concatenated to a string

uno:[connection],params;[protocol],params;[objectname]

An example Uno URL looks like:

uno:socket,host=localhost,port=2002;urp;StarOffice.ServiceManager

For more information about Uno URLs please consult http://udk.openoffice.org/common/man/spec/uno-url.html

A string similiar to the uno-url is used to configure the accepting process, for instance the office. . You can start the office with

soffice "-accept=socket,host=0,port=2002;urp;"

. Note that this string is not specified as strong as the uno-url and other programs may define there own format (e.g. the uno tool coming with the odk expects a different format). One speciality of the socket connection part is, that you can use "host=0", which means accept on every network interface available on the current machine including localhost. The "host=0" part cannot be used for connecting to a resource.

Additionally, you don't need to specify the object name, as the office eitherway exports multiple objects (StarOffice.NamingService, StarOffice.ServiceManager and [new] StarOffice.ComponentContext).

What's the purpose of the UnoUrlResolver?

The UnoUrlResolver gets a remote object for a service name specified in an uno-url, especially a StarOffice.ServiceManager. Then, you use the the service managers XNamingService interface in order to retrieve the service manager 'registeredObject' via getRegisteredObject in order to be able to queryInterface() for a XMultiServiceFactory. Remember, that the remote OpenOffice process has fulfilled its startup phase before the naming service reference is returned. This is necessary to guarantee the availability of all services. As you can see, the naming service is only a container for the service manager. This is done for flexibility reasons, because future versions may export more objects than only the service manager. Understand the uno-url as an entry point into another process; after that, everything else should be handled via normal UNO calls. Perhaps future versions also will remove the naming service's ability to remove and add objects, which obviously doesn't make any sense for remote processes.

How can I be event notified when a remote bridge is being disposed?

A XComponent notifies its event listeners when it is being disposed. Unfortunately a reference to a UnoUrlResolver object is not sufficent to receive a dispose event notification. You'll need at least a connector and a bridge factory service (see com.sun.star.comp.urlresolver.UnoUrlResolver in the jurt directory for more details) which you can query for a XComponent interface. This queried reference can be used to add a dispose event listener like this:

     String connection = "socket,host=localhost,port=2002";
     String protocol = "urp";
     Object connector = _xMultiServiceFactory.createInstance("com.sun.star.connection.Connector");
     XConnector connector_xConnector = (XConnector)UnoRuntime.queryInterface(XConnector.class, connector);
     XConnection xConnection = connector_xConnector.connect(connection);
     xBridge = xBridgeFactory.createBridge(connection + ";" + protocol, protocol, xConnection, null);
     XComponent component = (XComponent)UnoRuntime.queryInterface(XComponent.class, component);
     component.addEventListener(...);     
   

How can I check out the UDK www documentation?

The documentation for the udk project, which can be viewed via http://udk.openoffice.org, can be checked out using the following CVS command

   $ cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www 
If you don't want the generated C++ module reference documents you might want to save these commands into a script or batch file and run it from the command shell:
   cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www/common
   cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www/cpp/man
   cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www/java
   cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www/images
   cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www/bylaws.html
   cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www/documentation_structure.html
   cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www/faq.html
   cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www/index.html
   cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www/project_discuss.html
   cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www/project_issues.html
   cvs -d :pserver:anoncvs@anoncvs.openoffice.org:/cvs -z3 co oo/udk/www/project_navbar.html
 

Where can I find more information about the UNO security model?

Please follow http://udk.openoffice.org/common/man/draft/uno_security.html. The main goal of this draft is to provide a generic API to wrap existing security implementations, though the draft is based on java security and semantics. There are details to be discussed, marked in red, e.g., remote transparency.

Where can I find more information about the UNO CORBA bridge?

Bridging UNO and CORBA is no trivial task, as both component models are based on different fundamental concepts. Therefore, we want to write down the ideas about how to deal with these fundamental differences, before beginning implementation. Please follow http://udk.openoffice.org/common/man/concept/uno_corba.html for more information. The document currently contains only some aspects that we will have to deal with. The document is supposed to grow rapidly during the next weeks. Any input on this from the community is very welcome. The main goal is to get a CORBA-bridge that supports all features necessary to communicate with the GNOME desktop (http://www.gnome.org). The component model used in GNOME is BONOBO, which is built on top of ORBIT, an open source CORBA ORB (Object Request Broker). A CORBA-UNO bridge would, e.g., allow to script OpenOffice with a GNOME scripting language. The secondary goal is to develop a 'generic' CORBA-UNO-bridge, that allows communication with an arbitrary ORB. This would allow OpenOffice to seamlessly integrate into any CORBA environment.

Where can I find more information about the SOAP-UNO integration?

Please have a look at http://udk.openoffice.org/common/man/draft/soap.html.

Where can I find more information about the OpenOffice Bonobo integration?

A brief overview about the project OpenOffice - Bonobo Integration can be found at http://whiteboard.openoffice.org/bonobo/. Something about motivation and goals of this project is written there. We have checked in some code into CVS, enabling OpenOffice to be a Bonobo server for containers like Nautilus. Everyone is welcome to contribute ideas or code, on how to bring OpenOffice and GNOME closer together on the level of component technology.


This FAQ consists of questions and answers posted to the dev@udk.openoffice.org mailing list.

Maintainer: Jörg Brunsmann.
Last modified: Wednesday May 1, 2002.