Blog Archives

Mirror mailing list

To mirror the current Webobjects mailing list, you can use

cd /tmp
wget -N -np -r -l3 -nc https://lists.apple.com/archives/webobjects-dev/

You will get a directory tree, which is searchable with

grep -Hr "needle"

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>';

Oracle JDBC

The URL:

jdbc:oracle:thin:@<server>:1521:<sid>
jdbc:oracle:thin:@<server>:1521/<service_name>

The driver:

oracle.jdbc.OracleDriver

WebObject questions

Q: How I can change the templates of Java files, which Eclipse creates for a new WebObject Application?
A: I found the template files within the Eclipse plugin folder:
/home/arothe/WODevelopment/Tools/eclipse-java-neon-3/plugins/org.objectstyle.wolips.templateengine_4.6.20170831.10/ProjectTemplates/<project type>/Sources/__basePackage_folder__
There it is possible to add the changed _isSupportedDevelopmentPlatform() method for Linux.

Q: How I can add actions or keys to a component?
A: Hold down the STRG key and click with the left mouse button on the name of the action/key within the WOD file view. This will add Java code to the associated Java file if the implementation doesn’t exist, or it will navigate you to the method in the Java file.

Q: Which bindings are possible for a component?
A: Open the WOD-file and click on a component entry. Press CTRL+Space to open a list of valid properties. Another method is to open the view “Bindings” of WOLips.

Q: How I can set the WebObjects and WOnder API Docs to get a mouse over help in Eclipse?
A: The JavaDocs are linked on WOCommunity.org. All libraries, which you can add to the project build path, have a property called javadoc, which is set by WOLips to the content of wo.api.root (defined within wolips.properties). So the best way would be to mirror the necessary JavaDoc files into that directory. Try to use:

# cd /home/arothe/WODevelopment/Libraries/WOnder/Developer/Documentation
# wget -nH --cut-dirs=2 --no-parent --recursive --level=inf --page-requisites --wait=1 --reject-regex='index.html\?(.*)' http://wocommunity.org/documents/javadoc/WebObjects/5.4.2/

It is not possible to use the URL direct as JavaDoc location on the build path, it will be overwritten by WOLips with the configured wo.api.root entry. The property must be a valid filesystem folder, an URL is not allowed. So the simplest solution is to copy all files into a local folder.

Q: How I can display the content of a database table within a web page?
A: It is possible to display multiple records with WORepetition. There you can set a list of records (as NSArray or List, which comes back from a Database query). The attribute “item”is the current record within the table. So you can refer to it on a click or something. For every attribute of the EnterpriseObject you have to use e.g. a WOString, the “value”is mapped to item.attribute. You can also use a method within the page component class, which translates the DB attribute into a huma-readable value.

WebObjects and GWT

Today I had the idea, that I could use GWT (Google WebToolkit) together with WebObjects. I’m not a HTML programmer, so my webpages are not really nice. It would be better to develop Javacode and put the web components together with a framework.

On the internet I found a tool to combine WebObjects and GWT: WOGWT.

First I downloaded the GWT plugin for Eclispe 4.6: Install instructions.

First problem could be: the GWT version is now 2.7, but the WOGWT uses 2.5?

Download the WOGWT latest version 0.6 and unzip it into /home/arothe/Libraries/WOnder/Library/Frameworks. Now it is time for a simple Hello World example project. I created a new WebObject Application within Eclipse and added the new WOGWT framework to the build path.

The application doesn’t start, I have to add both ERExtensions and ERJars framework.

Now I have to set the path to the GWT SDK within the Eclipse preferences. But it doesn’t work, because there is not “tools” folder. I think, that is the time to download the whole SDK.

WebObjects & WOnder Examples (2)

MooToolsExample
It runs out of the box, no changes necessary.

ERMovies
Add the frameworks ERCoreBusinessLogic and ERJavaMail to the project build path within Eclipse.

ERModernMoviesDemo
Add the frameworks ERCoreBusinessLogic and ERJavaMail to the project build path.

ERJasperReportsExample
Add the frameworks ERCoreBusinessLogic, ERJavaMail, ERDirectToWeb, JavaDirectToWeb, JavaDTWGeneration and JavaEOProject to the build path. Another important point is the usage of Microsoft fonts like “Times” during the report generation. This results in an exception on my Linux machine. So I have to install the “mscorefonts” package first. Some Linux distributions don’t provide such a package, look around on the Internet to find an installer or something.

On CentOS7 this will work:

# su -
# yum install curl cabextract xorg-x11-font-utils fontconfig
# yum install https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm
# exit

ERComponentTour
It runs out of the box, no build path changes necessary. But the Captcha framework contains an error. It cannot create JPEGs for the Captcha. Currently I cannot find a solution, I opened an issue on GitHub.

BackgroundTasks
It runs out of the box, no changes necessary.

ERPDFExamples
It runs out of the box, no changes necessary.

WebObjects & WOnder Examples

I have tried some examples today, but a lot won’t work. Damn.

Movies

This example you can find on ~/WODevelopment/WonderSource/Examples/Misc/Movies. After the import of the project into Eclipse I started it as WOApplication. Choose the class er.movies.Application as start point. The console window displays an exception:

java.lang.NoClassDefFoundError: er/corebusinesslogic/ERCoreUserInterface

Seems to be simple, add a WebObjects library to the build path of the project: ERCoreBusinessLogic. Restart the application. The next exception:

java.lang.ClassNotFoundException: er.directtoweb.ERDirectToWeb

Now add the library ERDirectToWeb to the project. Restart the application. Repeat that x times, or simply add the following libraries to the project too:


ERJavaMail
JavaDirectToWeb
JavaEOProject
JavaDTWGeneration

Now, the application starts. But there is a warning:

Your application is not running on a supported development platform. AutoLaunch will not work.

This means, you have to copy the visible URL into a browser’s address line to see the example. Very annoying. Google provides a solution:

public boolean _isSupportedDevelopmentPlatform() {
	boolean result = super._isSupportedDevelopmentPlatform();
	if (!result) {
		result = System.getProperty("os.name").equals("Linux");
	}
	return result;
}

The warning will be replaced with another warning (WTF?):

Unable to locate /usr/bin/open on your computer, AutoOpen launch will not work

Seems that Ant will open a browser by calling the statement above. Try to symlink Firefox:

# su -
# ln -s /usr/bin/firefox /usr/bin/open
# exit

Restart the application and (surprise, surprise!) the Firefox displays the Movies application!

Project Wonder investigations

After some hours I found a reference to the /System/Library/Frameworks in the build process of the Wonder source (Build/build/generic.xml). But the System directory doesn’t exist in my installation, until I create it manually. So the directory is empty, but I think, the build process of WOnder looks there for the WebObjects frameworks.

I uncompressed the WOInstaller.jar and I found in the com.mdimension.woinstaller.Main a hint:

On non-OS.X systems (as my Linux) the original directory structure will be shuffled. The original /System/Library is moved to /Library, the original /Library is moved to /Local/Library. I think, this is important for the wolips.properties file.

The start of the WOInstaller with an os.name property with the value “os x” will not work (this could bypass the folder shuffle), it results in an exception in java.lang.UNIXProcess$Platform.get(). With this knowledge I have switched the folders back after the normal installation:

# cd /home/arothe/WODevelopment/Libraries/WOnder
# mkdir System
# mv Library System/.
# mv Local/Library Library
# rm -rf Local

Now the mapping is like the following, it matches with the documentation (which refers OS X often):

wo.system.frameworks=/home/arothe/WODevelopment/Libraries/WOnder/System/Library/Frameworks
wo.local.frameworks=/home/arothe/WODevelopment/Libraries/WOnder/Library/Frameworks
wo.user.frameworks=/home/arothe/WODevelopment/Libraries/WOnder/User/Library/Frameworks

Within Eclipse projects the build.xml needs the wolips.properties on /home/arothe/WODevelopment/Libraries/WOnder/Library/Application Support/WOLips. But it creates the path from ${user.home}, which is /home/arothe but not /home/arothe/WODevelopment/Libraries/WOnder. So I have set the property user.home within Eclipse on the global level for Ant within “Windows->Preferences->Ant->Runtime->Properties” to the new path (it seems that I cannot set this per project).

The Wonder source doesn’t need a wobuild.properties nor build.properties within the WonderSource folder. It uses the wolips.properties on “/home/arothe/WODevelopment/Libraries/WOnder/Library/Application Support/WOLips/wolips.properties” which I have symlinked to “/home/arothe/WODevelopment/wolips.properties”. Also the build.xml of the Eclipse projects use this path.

To start the build process of the Wonder source, we need to define the new user.home too:

# cd ~/WODevelopment/WonderSource
# ant -Duser.home=/home/arothe/WODevelopment/Libraries/WOnder frameworks

After these changes all is fine. The Wonder source compiles with Ant, the projects in Eclipse can be run and installed.

To finish the last step, the installation of the frameworks on the local webserver, I have found a property “wo.server.root”, which is defined in WonderSource/Build/build/default.properties as /Library/WebServer/Documents/WebObjects. This I have changed to “/srv/www/htdocs/WebObjects” within the wolips.properties (it overrides the default settings). I have to execute the following statement as root:

# su -
# cd /home/arothe/WODevelopment/WonderSource
# ant -Duser.home=/home/arothe/WODevelopment/Libraries/WOnder frameworks.install

This runs successsfully, all frameworks are installed in /srv/www/htdocs/WebObjects/Frameworks.