General

Hey, the OpenOffice.org 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 any 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.org?

In the near future, there will be an Office Development Kit available for download beside the openoffice.org-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.org 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.org, or write solutions with OpenOffice.org, then the ODK fits your needs. The UDK is a stand alone object model, that can be used without OpenOffice.org. 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.org.

The Office Development Kit enables software engineers to develop components for OpenOffice.org without the need of the bulky OpenOffice.org build environment. Thus, the ODK includes the binaries of the base libraries (+ im
port 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 and a 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.org build and will be available as an separate 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. 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 does not appear to be 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 used. To see more the differences between UNO and CORBA, please have a look on the following comparison.

Accessing the whole StarOffice API from Java, to implement your own applications.

The project is just starting, so please be aware there may be bugs, incomplete documentation, install problems, etc. We would like everyone with interest in OpenOffice.org and Java to contribute to this project, or just use the bean in their Java application.

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://developers.sun.com/), 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 high level office API questions.

How do I generate C++ type definitions?

. create .idl files describing the interface

. generate .urd file using unoidl

. merge the new type(s) into the system registry with regmerge

. create the C++ types using cppumaker (for Java: use javamaker)

. 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 that 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:

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.org, you'll have to register your service as a external component. To achieve this you'll need to follow these steps:

. copy your DLL into the .../program directory

. copy the tool regcomp into the .../program directory. You will find this tool in the UDK module cpputools

. use the regcomp tool

$ regcomp -register -r applicat.rdb -c foo.dll

. If you develop your own interfaces or 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.

. 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)

. 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:

How many bridges exist?

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 enum 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 least amount 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 RISC 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

Using these arguments, you can force OpenOffice.org 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 which are the same as the pick list from the UI,the options are stored in the soffice.ini/sofficerc.

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 type library 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 depent types will be generated recursively, so that you get all the necessary C++ type declarations you need to build your component.

After the regmerge the applicat.rdb contains all types, the ones that comes with Openoffice.org and your new one. Note the regmerge command only modifies the first file, the others are opened read only.

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:

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 directory oo/udk/stoc. Inside the stoc directory the loader is built in the directory source/loader. The built library is called cpld.dll.

What if regcomp does not find your C++ service

If you are testing C++ library registration of your Calc.XlsxExport
service with regcomp like this:

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 modeling 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 guides 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 bridge, maybe UNO-COM, which would require unique identifiers.
How can I configure the office to be started in listening mode ?
There are two ways.

. 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).

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

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 definitely better, more secure, to replace the 0 with localhost.

If you want to configure remote connect only for a certain user (in a network installation), you need to do the modification into the user dependent configuration directory in Setup.xml, above.

A string similar 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 either way 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.org 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 sufficient 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:

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

Please look at http://udk.openoffice.org/common/man/concept/uno_security.html. The main goal of this draft is to provide a generic API to wrap existing security implementations, this draft is based on Java security and semantics and may change. There are details being discussed, marked in red, for example 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 look at http://udk.openoffice.org/common/man/concept/uno_corba.html for more information.

This document currently contains only part that we will have to deal with during development of the bridge. The document is supposed to grow rapidly during the next weeks. Any input on UNO CORBA bridge from the community is very welcome, discussions take place on dev@udk.openoffice.org.

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 allow to script OpenOffice.org with a GNOME scripting language, for example.

The secondary goal is to develop a 'generic' CORBA-UNO-bridge, that allows communication with an arbitrary ORB. This would allow OpenOffice.org to seamlessly integrate into any CORBA environment.

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

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

A brief overview about the project OpenOffice.org - 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.org to be a Bonobo server for containers like Nautilus. Everyone is welcome to contribute ideas or code, on how to bring OpenOffice.org and GNOME closer together on the level of component technology.