Scripting in Java with NetBeans IDE

From Apache OpenOffice Wiki
Revision as of 11:45, 10 March 2009 by Arielch (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

This a "visual" guide for setting up the NetBeans IDE to create, compile and debug Java macros in OpenOffice.org.

Before starting you should be familiar with the technical documentation: OpenOffice.org Developer's Guide - Scripting Framework, in particular OpenOffice.org Developer's Guide - Scripting Framework - Writing Macros - Compiling and Deploying Java macros.

This tutorial aims to give a provisional solution until the concretation of the planned new OpenOffice.org Scripting Project Type in the OpenOffice NetBeans IDE plug-in (see OpenOffice NetBeans Integration - Planned Features).

We tried to choose the simplest way to do things that we could imagine.


Java configuration in OpenOffice.org Options dialog

The first step is to configure the JVM used by OpenOffice.org to listen for debugger connections (see Developer's Guide – Writing UNO Components – Running and Debugging Java Components).

1. select the menu Tools – Options... to execute the Options dialog:


Menu "Tools" - "Options"


2. in the Java options, check Use a Java runtime environment, and then select one of the JRE installed in your system:


"Java options" - "Use a Java runtime environment"


3. next step is to enter the debug options, for this purpose push the Parameters button in order to open a new dialog:


"Parameters"


4. in the Java Start Parameters dialog enter the first debug parameter -Xdebug and push the Assign button:


-Xdebug


5. then enter the second debug parameter: -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n, push the Assign button, and then OK:


Debug parameter


Finally push the OK button in OpenOffice.org Options dialog in order to confirm the settings and restart the application (in Windows close also the Quick-starter).

Setting the NetBeans Project

In this step-by-step tutorial we will create a NetBeans Project for a Java macro. We will use one of the existing examples that come with every OpenOffice.org installation: HelloWorld.java.

You can find this example in the share directory of your Office installation under

$(Office Basis layer)/share/Scripts/java/HelloWorld

for example:

in Linux
         /opt/openoffice.org/basis3.1/share/Scripts/java/HelloWorld

in Windows
         C:\Program Files\OpenOffice.org 3\Basis\share\Scripts\java\HelloWorld

Inside this folder you will find the following files:

    *   parcel-descriptor.xml
    *   HelloWorld.java
    *   HelloWorld.jar

Copy this folder with all its contents inside the user installation directory under

$(user)/Scripts/java/HelloWorld

for example:

in Linux
        /home/user_name/.openoffice.org/3/user/Scripts/java/HelloWorld

in Windows
        C:\Documents and Settings\user_name\ApplicationData\OpenOffice.org\3\user\Scripts\java\HelloWorld


New Project Wizard

In this section we will show how to use the New Project wizard to create our Scripting Project. We prefer here to use the Java Project with Existing Sources. Please notice that if you choose other way, the following explanations will not work.


1. Push the New Project... tool bar button to open the wizard:


Creating a New Project


2. Choose Project: in the left panel Categories, select Java, and in the right panel Projects choose Java Project with Existing Sources:


Java Project with Existing Sources


3. Name and Location: specify the name and location for the new project. In Project Name type HelloWorld, in Project Folder type a folder where you have writing privileges.


Scripting Project


4. Existing Sources: in Source Package Folders specify your path for $(user)/Scripts/java/HelloWorld


Choosing the sources


5. Includes & Excludes: in Includes type *.java in order to include only the Java source file in the build; in Excludes type *.jar and *.xml; then push the Finish button to conclude the wizard.


Includes & Excludes


6. if you have successfully created your new Scripting Project, you can now expand the project's node and open the HelloWorld.java source file. You will notice that the IDE underlines several errors, this is due to the failing imports: we must tell the Project where to find the Office packages.


Import errors will be fixed soon...


7. right-click on the Project's root node to execute the context menu, and choose the Properties menu item to edit the project's properties


Project's Properties


8. in the left panel, under Categories choose Libraries, and push the button Add JAR/Folder in the Compile tabbed pane.


Add JAR/Folder


9. browse your file system looking for the Office installation. You must select at least the following JAR files from the program/classes directory of your OpenOffice.org URE installation ($(URE inst)/ure/share/java/):

     juh.jar, jurt.jar, ridl.jar

     In Linux:
                 /opt/openoffice.org/ure/share/java
     In Windows:
                 C:\Program Files\OpenOffice.org 3\URE\java

And unoil.jar from the Office basis layer under $(Office Basis layer)basis3.1/program/classes/unoil.jar


     In Linux:
                 /opt/openoffice.org/basis3.1/program/classes/unoil.jar
     In Windows:
                 C:\Program Files\OpenOffice.org 3\Basis\program\classes\unoil.jar

Click OK to close the Add JAR/Folder dialog, then push OK to confirm this settings and close the Project Properties dialog.


Select the JARs


10. now that all imports have been fixed you can build your Scripting Project:


Building the project

Customizing the ANT build script

By default, the JAR file HelloWorld.jar is compiled on the dist directory inside your NetBeans Project folder. We need to place this JAR file inside the $(user)/Scripts/java/HelloWorld/ folder, this way the Scripting Framework can find our latest build.

To achieve this we will edit the ANT build script, so that every time we build the Project, HelloWorld.jar is copied form the dist directory to $(user)/Scripts/java/HelloWorld, and every time the Project is cleaned, it will be deleted.

In the Files window, expand the root node and open the ANT project build.xml.

It can look like this:

<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<project name="HelloWorld" default="default" basedir=".">
    <description>Builds, tests, and runs the project HelloWorld.</description>
    <import file="nbproject/build-impl.xml"/>
    <!--
 
    There exist several targets which are by default empty and which can be 
    used for execution of your tasks. These targets are usually executed 
    before and after some main targets. They are: 
 
      -pre-init:                 called before initialization of project properties
      -post-init:                called after initialization of project properties
      -pre-compile:              called before javac compilation
      -post-compile:             called after javac compilation
      -pre-compile-single:       called before javac compilation of single file
      -post-compile-single:      called after javac compilation of single file
      -pre-compile-test:         called before javac compilation of JUnit tests
      -post-compile-test:        called after javac compilation of JUnit tests
      -pre-compile-test-single:  called before javac compilation of single JUnit test
      -post-compile-test-single: called after javac compilation of single JUunit test
      -pre-jar:                  called before JAR building
      -post-jar:                 called after JAR building
      -post-clean:               called after cleaning build products
 
    (Targets beginning with '-' are not intended to be called on their own.)
 
    Example of inserting an obfuscator after compilation could look like this:
 
        <target name="-post-compile">
            <obfuscate>
                <fileset dir="${build.classes.dir}"/>
            </obfuscate>
        </target>
 
    For list of available properties check the imported 
    nbproject/build-impl.xml file. 
 
 
    Another way to customize the build is by overriding existing main targets.
    The targets of interest are: 
 
      -init-macrodef-javac:     defines macro for javac compilation
      -init-macrodef-junit:     defines macro for junit execution
      -init-macrodef-debug:     defines macro for class debugging
      -init-macrodef-java:      defines macro for class execution
      -do-jar-with-manifest:    JAR building (if you are using a manifest)
      -do-jar-without-manifest: JAR building (if you are not using a manifest)
      run:                      execution of project 
      -javadoc-build:           Javadoc generation
      test-report:              JUnit report generation
 
    An example of overriding the target for project execution could look like this:
 
        <target name="run" depends="HelloWorld-impl.jar">
            <exec dir="bin" executable="launcher.exe">
                <arg file="${dist.jar}"/>
            </exec>
        </target>
 
    Notice that the overridden target depends on the jar target and not only on 
    the compile target as the regular run target does. Again, for a list of available 
    properties which you can use, check the target you are overriding in the
    nbproject/build-impl.xml file. 
 
    -->
</project>


We will add the following:

    <!-- 
         This will copy the compiled jar 
         to the Scripts/java/HelloWorld directory 
    -->
    <target name="-post-jar">
        <copy overwrite="true" file="${dist.jar}" todir="${src.dir}"/>
    </target>
 
    <!-- 
        This will clean the copy of HelloWorld.jar
        in the Scripts/java/HelloWorld directory
    -->    
    <target name="-post-clean">
        <delete  file="${src.dir}/HelloWorld.jar" />
    </target>


Our new build.xml will be then:

<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<project name="HelloWorld" default="default" basedir=".">
    <description>Builds, tests, and runs the project HelloWorld.</description>
    <import file="nbproject/build-impl.xml"/>
    <!--
 
    There exist several targets which are by default empty and which can be 
    used for execution of your tasks. These targets are usually executed 
    before and after some main targets. They are: 
 
      -pre-init:                 called before initialization of project properties
      -post-init:                called after initialization of project properties
      -pre-compile:              called before javac compilation
      -post-compile:             called after javac compilation
      -pre-compile-single:       called before javac compilation of single file
      -post-compile-single:      called after javac compilation of single file
      -pre-compile-test:         called before javac compilation of JUnit tests
      -post-compile-test:        called after javac compilation of JUnit tests
      -pre-compile-test-single:  called before javac compilation of single JUnit test
      -post-compile-test-single: called after javac compilation of single JUunit test
      -pre-jar:                  called before JAR building
      -post-jar:                 called after JAR building
      -post-clean:               called after cleaning build products
 
    (Targets beginning with '-' are not intended to be called on their own.)
 
    Example of inserting an obfuscator after compilation could look like this:
 
        <target name="-post-compile">
            <obfuscate>
                <fileset dir="${build.classes.dir}"/>
            </obfuscate>
        </target>
 
    For list of available properties check the imported 
    nbproject/build-impl.xml file. 
 
 
    Another way to customize the build is by overriding existing main targets.
    The targets of interest are: 
 
      -init-macrodef-javac:     defines macro for javac compilation
      -init-macrodef-junit:     defines macro for junit execution
      -init-macrodef-debug:     defines macro for class debugging
      -init-macrodef-java:      defines macro for class execution
      -do-jar-with-manifest:    JAR building (if you are using a manifest)
      -do-jar-without-manifest: JAR building (if you are not using a manifest)
      run:                      execution of project 
      -javadoc-build:           Javadoc generation
      test-report:              JUnit report generation
 
    An example of overriding the target for project execution could look like this:
 
        <target name="run" depends="HelloWorld-impl.jar">
            <exec dir="bin" executable="launcher.exe">
                <arg file="${dist.jar}"/>
            </exec>
        </target>
 
    Notice that the overridden target depends on the jar target and not only on 
    the compile target as the regular run target does. Again, for a list of available 
    properties which you can use, check the target you are overriding in the
    nbproject/build-impl.xml file. 
 
    -->
 
    <!-- 
        This will copy the just builded jar 
        to the Scripts/java/HelloWorld directory
    -->
    <target name="-post-jar">
        <copy overwrite="true" file="${dist.jar}" todir="${src.dir}"/>
    </target>
 
    <!-- 
        This will clean the copy of HelloWorld.jar
        in the Scripts/java/HelloWorld directory
    -->    
    <target name="-post-clean">
        <delete  file="${src.dir}/HelloWorld.jar" />
    </target>
 
</project>


Please notice that these project properties dist.jar and src.dir may be different in your project if you have done things in a different way, or you are using another version. If there is an error in the build/clean process, please check the project.properties and the build-impl.xml files inside the nbproject folder.

Debugging

Now we can start debugging our Scripting Project.

First, set a line breakpoint in the source file HelloWorld.java:


019 set Break point.png


Then launch the office and run your Java macro in the Macro Selector, so that the office invokes the JVM in listening mode. This will start the listening mode, then you will have to run it again when debugging (if you do not want to run it twice, you can start the listening mode by instantiating any Java component or running any other Java macro).

In Linux, you can launch the application from the command line, and once the listening mode is started you will see (depending on your shell) a message like this one:


Console OOo LISTENING.png


Now that we are sure that the JVM is listening we can start debugging.

Choose the menu Run – Attach debugger...


022 attach debugger.png


You must set the following configuration and click OK to connect the Java Debugger to the listening JVM.


023 attach debugger config.png


Once the debugger connects to the listening JVM, NetBeans switches to debug mode: in the Output window you can read a message in the Debugger Console. If the message is as follows, the connection on port 8000 has been successfully established:


024 user program running.png


Now you can run the Java macro to debug it. Choose the menu Tools – Macros – Run Macro...


020 launch OOo JVM.png


And run the HelloWorld Java macro:


021 launch OOo JVM macro selector.png


The program will stop in your first breakpoint:


025 debugging.png
Personal tools