Monthly Archives: October 2017

Webobjects application deployment on Java1.7 server

My first WebObjects application runs now within Eclipse, and I use the context menue “WO Lips Ant Tools”->”Install” to create a deployable archive. But my target server has only Java 1.7, my Eclipse runs on Java 1.8. The server will not use the compiled classes, because of the wrong major.minor class file version.

Before you rebuild frameworks, close Eclipse!

The frameworks of WebObjects/WOnder are compiled with Ant during the installation process. You can found them within /home/arothe/WODevelopment/Libraries/WOnder (which is my HOME) and there are some copies of the frameworks:

1. ${HOME}/Libraries/WOnder/Root
2. ${HOME}/Libraries/WOnder/Library/Frameworks
3. ${HOME}/Libraries/WOnder/Library/WebObjects/lib
4. wo.server.root

If you build the WOnder frameworks with Ant on the commandline, they will be built on 1.
If you install the WOnder frameworks with Ant on the commandline, they will be installed on 2. and 3. and a copy is also created on wo.server.root (i.e. /tmp/WebObjects)

It could be a good idea to remove all old frameworks from these locations before rebuilding. To build/install the frameworks, Ant will use the default Java installation, which is on my Development system Java1.8. But you can find on /home/arothe/WODevelopment/WonderSource/Build/build/default.properties three properties, which define the expected Java version

build.compiler=javac1.5
compiler.source=1.5
compiler.target=1.5

These are the defaults for WOnder6, WOnder7 needs Java 1.8, so it could be better to downgrade the WOnder version for the Java1.7 target system (checkout the latest tag/release for Wonder6 on GitHub):

cd ${HOME}
rm -rf WonderSource
git clone https://github.com/wocommunity/wonder.git WonderSource
cd WonderSource
git checkout tags/wonder-6.1.5

Now build the frameworks and install them.

cd ${HOME}
cd WonderSource
ant -Dant.build.javac.source=1.7 -Dant.build.javac.target=1.7 -Duser.home=/home/arothe/WODevelopment/Libraries/WOnder frameworks frameworks.install

This creates the frameworks on the four locations above. The current user must have write access to wo.server.root, otherwise you will get a build error.

Now reopen Eclipse and rebuild the project. There shouldn’t be any errors. To create the archives for the application, Eclipse will use Ant, which runs again on Java1.8. First, remove the old archives from the locations:

1. ${HOME}/Libraries/WOnder/Library/WebObjects/Applications/${projectname}-Application.tar.gz
2. ${HOME}/Libraries/WOnder/Library/WebObjects/Applications/${projectname}-WebServerResources.tar.gz
3. ${HOME}/Libraries/WOnder/Library/WebObjects/Applications/${projectname}.woa
4. ${HOME}/Libraries/WOnder/Library/WebObjects/Applications/Split/WebObjects/${projectname}.woa
5. ${PROJECT}/dist/*

Now rebuild the archives with a right-click on the projectname within Eclipse and “WO Lips Ant Tools”->”Install”. Then copy the tar.gz files to the server and decompress the *-Application.tar.gz i.e. on /opt/Apple/Local/Library/WebObjects/Applications, which creates a new folder ${projectname}.woa.

cd /opt/Apple/Local/Library/WebObjects/Applications/${projectname}.woa
./${projectname}

It should start the application (or give some hints, which is wrong).

To find the location for the second archive (${projectname}-WebServerResources.tar.gz), which the install process generates, you should look into your WebObjects configuration of the Apache webserver. There is a .conf file, which contains the property “WebObjectsDocumentRoot”. Decompress the archive into the subdirectory WebObjects of the configured directory (i.e. WebObjectsDocumentRoot=/var/www/html, decompress into /var/www/html/WebObjects).

You should check your JDBC driver classes (and also all other 3rd party JARs), that they have the correct class version (compiled with 1.7 instead of 1.8).

Move object between EditingContexts

I have created an EnterpriseObject and have registered it on the default EditingContext.

MyObject my = MyObject.createMyObject(session.defaultEditingContext(), "Foo");
session.defaultEditingContext().saveChanges();

Now, the object is related to this EditingContext. If I create another EOEditingContext and try to use the MyObject instance there as part of a relation, it will go wrong.

EOEditingContext ec = new EOEditingContext();
AnotherObject xyz = AnotherObject.createAnotherObject(ec, my, "Bar");
ec.saveChanges();

This produces an exception:

Cannot obtain globalId for an object which is registered in an other than the databaseContext's active editingContext

The problem is, that the instance of MyObject is not known within the second EOEditingContext. To correct that, the MyObject class has a method localInstanceIn(), which you can call:

EOEditingContext ec = new EOEditingContext();
my.localInstanceIn(ec);
AnotherObject xyz = AnotherObject.createAnotherObject(ec, my, "Bar");
ec.saveChanges();

Derby JDBC

On a Linux with SystemD you can use the following service file (Derby has been installed on /opt/db-derby-10.13.1.1-bin):

[Unit]
Description=Apache Derby Database Network Server
After=network.target

[Service]
Type=simple
Environment=CLASSPATH=/opt/db-derby-10.13.1.1-bin/lib/derby.jar:/opt/db-derby-10.13.1.1-bin/lib/derbynet.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_cs.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_de_DE.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_es.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_fr.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_hu.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_it.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_ja_JP.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_ko_KR.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_pl.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_pt_BR.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_ru.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_zh_CN.jar:/opt/db-derby-10.13.1.1-bin/lib/derbyLocale_zh_TW.jar
WorkingDirectory=/var/lib/derby
StandardOutput=syslog
User=andre
ExecStart=/usr/bin/java -Dderby.system.home=/var/lib/derby org.apache.derby.drda.NetworkServerControl start
ExecStop=/usr/bin/java -Dderby.system.home=/var/lib/derby org.apache.derby.drda.NetworkServerControl shutdown

[Install]
WantedBy=multi-user.target

Copy this file to /usr/lib/systemd/system as apache-derby.service and execute as root:

# systemctl enable apache-derby.service
# systemctl start apache-derby.service

The databases will be generated at /var/lib/derby.

To test the Derby server start the ij tool:

# cd /opt/db-derby-10.13.1.1-bin/bin
# ij

CONNECT 'jdbc:derby://localhome:1527/atest;create=true';

The database atest should be generated within /var/lib/derby/atest. If there is an error, check your apache-derby service and your local firewall (open port 1527).

To use the database server within EOModeler you can set:

database url:      jdbc:derby://<server>:1527/<database name>
JDBC library:      derbyclient.jar
JDBC driver class: org.apache.derby.jdbc.ClientDriver

User Management

Per default Derby doesn’t need an user to access a database. To enable user authentication you should add an user with full access to the database:

# ij

CONNECT 'jdbc:derby://localhome:1527/atest';
CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.user.<an username>', '<a password>');
CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.database.fullAccessUsers', '<an username>');
CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.connection.requireAuthentication', 'true');
EXIT;

If you define an user, you will have to enable the authentication mode for Derby too. Restart the apache-derby.service to enable the authentication after the calls above. Now it is necessary to provide username and password for this specific database “atest” within EOModeler.

The new JDBC url toconnect with ij would be:

CONNECT 'jdbc:derby://<server>:1527/<database name>;user=<username>;password=<secret>';