Wednesday, October 29, 2008

CommandlineCodeGen Debugging Tricks

If you need to get debugging level logging for the commandlinecodegen under both Windows or Linux, then change the log4j.properties in this file:

$CODEGEN_HOME/compile/lib/ext/log4jProperties.jar
Then modify the first line to be DEBUG instead of ERROR.

Activating the debug mode in eDesigner

Edit the %EDESIGNER_HOME%/bin/runed.bat file and search for the line that contains

-J-Drun.mode=run
And change it to
-J-Drun.mode=debug

Also, in the same folder edit the log4j.properties rootLogger.
Change it from ERROR to DEBUG.

Restart your eDesigner.

You can find the log file in %EDESIGNER_HOME%/userdir/system/ide.log

Tuesday, September 30, 2008

SAP CommandLinceCodegen in Linux... Oh dear...

Update: This problem has been fixed in Java CAPS 5.1.3 Update 3

I'm getting this error in the log when I'm trying to compile my project that makes use of the BAPI eWay:


[CODELET] com.stc.otd.codegen.OtdCodeGenException: javaClass: BapiOtdGenerator.validateSapJars(): The following .jar file(s) need to be part of the JVM environment before source code can be compiled: sapjco.jar. See documentation for more information.
[CODELET] at com.stc.sapbapi.codegen.bapi.BapiOtdGenerator.validateSapJars(BapiOtdGenerator.java:233)
[CODELET] at com.stc.sapbapi.codegen.bapi.BapiOtdGenerator.compile(BapiOtdGenerator.java:170)
[CODELET] at com.stc.sapbapi.codegen.bapi.BapiOtdGenerator.generate(BapiOtdGenerator.java:312)
[CODELET] at com.stc.otd.codegen.BaseGenerator.generate(BaseGenerator.java:255)
[CODELET] at com.stc.sapbapi.codegen.SAPEWayCodeletBase$OutboundCodelet$SAPOutboundJCECodelet.generateOtdJarFile(SAPEWayCodeletBase.java:873)
[CODELET] at com.stc.sapbapi.codegen.SAPEWayCodeletBase$OutboundCodelet$SAPOutboundJCECodelet.generateFiles(SAPEWayCodeletBase.java:924)
[CODELET] at com.stc.codegen.anttaskImpl.driver.CodeletProcessor.execute(CodeletProcessor.java:89)
[CODELET] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[CODELET] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[CODELET] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[CODELET] at java.lang.reflect.Method.invoke(Method.java:585)
[CODELET] at com.stc.codegen.anttaskImpl.CodeGenAntTaskImpl.execute(CodeGenAntTaskImpl.java:117)
[CODELET] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
[CODELET] at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
[CODELET] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[CODELET] at java.lang.reflect.Method.invoke(Method.java:585)
[CODELET] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:105)
[CODELET] at org.apache.tools.ant.Task.perform(Task.java:348)
[CODELET] at org.apache.tools.ant.Target.execute(Target.java:357)
[CODELET] at org.apache.tools.ant.Target.performTasks(Target.java:385)
[CODELET] at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1329)
[CODELET] at org.apache.tools.ant.helper.SingleCheckExecutor.executeTargets(SingleCheckExecutor.java:38)
[CODELET] at org.apache.tools.ant.Project.executeTargets(Project.java:1181)
[CODELET] at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:416)
[CODELET] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
[CODELET] at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
[CODELET] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[CODELET] at java.lang.reflect.Method.invoke(Method.java:585)
[CODELET] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:105)
[CODELET] at org.apache.tools.ant.Task.perform(Task.java:348)
[CODELET] at org.apache.tools.ant.Target.execute(Target.java:357)
[CODELET] at org.apache.tools.ant.Target.performTasks(Target.java:385)
[CODELET] at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1329)
[CODELET] at org.apache.tools.ant.Project.executeTarget(Project.java:1298)
[CODELET] at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
[CODELET] at org.apache.tools.ant.Project.executeTargets(Project.java:1181)
[CODELET] at org.apache.tools.ant.Main.runBuild(Main.java:698)
[CODELET] at org.apache.tools.ant.Main.startAnt(Main.java:199)
[CODELET] at org.apache.tools.ant.launch.Launcher.run(Launcher.java:257)
[CODELET] at org.apache.tools.ant.launch.Launcher.main(Launcher.java:104)


Whenever you have a classpath problem with ant, run the ant command with the -diagnostics flag.

Here is what I get ("." represents irrelevant stuff that I've removed):

$ /export/apache-ant-1.7.0/bin/ant -verbose -lib compile/lib/ext -Dcommandline.dir=. -propertyfile /export/scripts/buildProps/p2pd/build.SEP_CAS_FirstContDate.properties -diagnostics
.
.
.
-------------------------------------------
ANT_HOME/lib jar listing
-------------------------------------------
.
.
.
sapjco.jar (304078 bytes)
.
.
.
-------------------------------------------
USER_HOME/.ant/lib jar listing
-------------------------------------------
.
.
.
sapjco.jar (304078 bytes)
.
.
.
java.class.path : /export/apache-ant-1.7.0/lib/ant-launcher.jar:/export/commandlinecodegen/compile/lib/ext/ldap.jar:/export/commandlinecodegen/compile/lib/ext/com.stc.antlrimpl.jar:/export/commandlinecodegen/compile/lib/ext/sapjco.jar:/export/commandlinecodegen/compile/lib/ext/openide.jar:/export/commandlinecodegen/compile/lib/ext/log4jProperties.jar:/export/commandlinecodegen/compile/lib/ext/commons-logging.jar:/export/commandlinecodegen/compile/lib/ext/log4j.jar:/export/commandlinecodegen/compile/lib/ext:/home/eaiadmin/.ant/lib/sapjco.jar:/export/apache-ant-1.7.0/lib/ant-jai.jar:/export/apache-ant-1.7.0/lib/ant-antlr.jar:/export/apache-ant-1.7.0/lib/ant-starteam.jar:/export/apache-ant-1.7.0/lib/ant-jdepend.jar:/export/apache-ant-1.7.0/lib/ant-apache-oro.jar:/export/apache-ant-1.7.0/lib/ant-trax.jar:/export/apache-ant-1.7.0/lib/ant-apache-regexp.jar:/export/apache-ant-1.7.0/lib/ant-jmf.jar:/export/apache-ant-1.7.0/lib/ant-jsch.jar:/export/apache-ant-1.7.0/lib/ant-apache-bsf.jar:/export/apache-ant-1.7.0/lib/ant-netrexx.jar:/export/apache-ant-1.7.0/lib/ant-swing.jar:/export/apache-ant-1.7.0/lib/sapjco.jar:/export/apache-ant-1.7.0/lib/xercesImpl.jar:/export/apache-ant-1.7.0/lib/ant-apache-bcel.jar:/export/apache-ant-1.7.0/lib/ant-stylebook.jar:/export/apache-ant-1.7.0/lib/ant-javamail.jar:/export/apache-ant-1.7.0/lib/ant-junit.jar:/export/apache-ant-1.7.0/lib/ant-commons-net.jar:/export/apache-ant-1.7.0/lib/ant-commons-logging.jar:/export/apache-ant-1.7.0/lib/ant-weblogic.jar:/export/apache-ant-1.7.0/lib/ant-apache-log4j.jar:/export/apache-ant-1.7.0/lib/ant.jar:/export/apache-ant-1.7.0/lib/xml-apis.jar:/export/apache-ant-1.7.0/lib/ant-nodeps.jar:/export/apache-ant-1.7.0/lib/ant-testutil.jar:/export/apache-ant-1.7.0/lib/ant-launcher.jar:/export/apache-ant-1.7.0/lib/ant-apache-resolver.jar:/export/jdk1.5.0_15/lib/tools.jar
.
.
.


So the sapjco.jar is definitely on the classpath. But why are we getting this error then:

com.stc.otd.codegen.OtdCodeGenException: javaClass: BapiOtdGenerator.validateSapJars(): The following .jar file(s) need to be part of the JVM environment before source code can be compiled: sapjco.jar. See documentation for more information.


In this case we should have a look at the underlying validation mechanism. This is a bit naughty... don't tell your boss. ;)

I use this command to find the jar that contains the BapiOtdGenerator class.


for jar in $(find /export/commandlinecodegen -name "*jar"); do unzip -l $jar|grep BapiOtdGenerator; if [ $? == 0 ]; then echo $jar; fi; done


After that "jad" can be quite helpful.
http://www.kpdus.com/jad.html

Have a look at the validateSapJars method in the resulting BapiOtdGenerator.jad file.

A while back I posted about my frustration of not being able to use the eWay Development Kit under Linux. The reason I was not able to use is was that the developer of the eDK has hard coded all directory paths to use "\" instead of "/". Well, really he should have used java.io.File.pathSeparator. Here we have a very similar problem of developers never being exposed to the world of Linux.

The method in question uses the StringTokenizer class to split the classpatch by ";". Well, that will of course only work on Windows, because Linux uses ":". So no matter where I put the sapjco.jar the validation will never succeed. How unfortunate.

Since the commandlinecodegen is supported on Linux I have no doubt that this bug will be fixed. It's pretty easy to fix after all. In fact, java.lang.System.getProperties() will give you the right value that is needed.

The thing that annoys me the most is that Java was meant to be platform neutral.

So, no commandlinecodegen in Linux for BAPIs then I guess...

SAP Enabling the Commandline Codegen (Linux) (5.1.3)

I had previously posted about debugging JCo problems with Java CAPS here:
http://jcapsblogger.blogspot.com/2007/11/what-to-do-if-you-have-issues-with-jco.html

Now I will extend this method to include the commandline codegen tool for Java CAPS.

First of all, a brief refresher on how to get the commandline codegen to work.
You MUST use a JDK that is version 5, otherwise your builds won't succeed.
Your ant version should be version 1.7.

A sample build.properties file looks like this:


commandline.rep.url=http://eaiutil4.ird.govt.nz:12000/rv2
commandline.rep.user=codegen
commandline.rep.pass=codegen
commandline.rep.dir=localrepository
commandline.rep.projectName=CORE/util/PingWebClient/dp
commandline.rep.projectDeployName=dpPingWebClient
commandline.rep.projectDeploymentTag=
commandline.rep.projectBranchName=
commandline.esr.select=
commandline.esr.ignore=


No let us install the JCo stuff.

Copy the sapjco.jar to ~/.ant/lib
Copy the librfccm.so and libsapjcorfc.so into $JDK_HOME/jre/lib/i386.

WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!!
DOES NOT WORK!!!
WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!!

Read next blog post to find out why.

Update from Mon, 27 October, 2008: This problem has been fixed in Java CAPS 5.1.3 Update 3, so the above instructions will now work.

Monday, September 29, 2008

stop_domain1.sh enhancement

Sometimes it happens that the stop_domain1.sh script fails because some JVM setting was not done right.

It is then necessary to kill -9 all processes belonging to the Java CAPS Domain.

This script will automatically kill the domain if the default shutdown command fails.


#!/bin/sh

INSTALL_DIR=/home/syk4/JavaCAPS513/logicalhost/is
DOMAIN_NAME=domain1


"$INSTALL_DIR/bin/isadmin" stop-domain $* $DOMAIN_NAME

# Added by sebastian.krueger@ird.govt.nz
# 0 == ok
# 1 == broken

if [ $? == 1 ]; then
echo
echo "Killing the Domain by force!!"

for job in `ps ax|egrep 'isprocmgr_domain1|is_domain1|domain1.*stcms.exe'|grep -v grep|awk '{print $1}'`; do kill -9 $job; done
fi




To install this script edit the $DOMAIN_HOME/lib/stopdomain.sh.template to look like this:

#!/bin/sh

INSTALL_DIR=$INSTALL_DIR$
DOMAIN_NAME=$DOMAIN_NAME$

"$INSTALL_DIR/bin/isadmin" stop-domain $* $DOMAIN_NAME

# 0 == ok
# 1 == broken

if [ $? == 1 ]; then
echo
echo "Killing the Domain by force!!"

for job in `ps ax|egrep 'isprocmgr_$DOMAIN_NAME$|is_$DOMAIN_NAME$|$DOMAIN_NAME$.*stcms.exe'|grep -v grep|awk '{print $1}'`; do kill -9 $job; done
fi

Java CAPS TimeZone Update for JVM

In New Zealand we changed to Summer Time yesterday.

After this change I found that several of our SUSE Linux Enterprise Servers had incorrect time (when using the "date" command).

After applying a patch from novell.com to fix this issue I found that the date command was now returning the correct time, but my Java CAPS logs were still on Winter Time.

I then found that this is a bug with the JVM.
For more info on this look here:
http://sunsolve.sun.com/search/document.do?assetkey=1-26-102836-1

You can fix it by downloading the Timezone Updater Tool from here:
http://java.sun.com/javase/tzupdater_README.html

Run the tzupdater.jar with the jre that is supplied with the domain. This will then update the timezone data for your domain and your logs will show the correct time.

Use the following one-liner in bash to apply the patch to all local jvm's:


for java in `find . -name java -type f -perm /+x`; do echo $java; $java -jar ~/tzupdater.jar -t; done

Wednesday, September 10, 2008

projectExport/Import Trap for young players

In Linux, if you run the exportProject.sh script (tested in 5.1.3 and 6.0.0) you get the following documentation:

./exportProject.sh
Usage: To export Projects/Environments, type in

exportProject.sh {username} {password} {branch name} {export file} {project paths} {environment paths}

To export both projects and environments:
eg. exportProject.sh user pwd "" /usr/jcaps/export.zip "Project1+Project2/SubProject" "Env1+Env2"

To export only projects:
eg. exportProject.sh user pwd "" /usr/jcaps/export.exp "Project1+Project2/SubProject" ""

To export a project from a given version control branch:
eg. exportProject.sh user pwd "BranchName" /usr/jcaps/export.exp "Project1" "Env1"
So you would then expect that the following should work:

./exportProject.sh Administrator STC "" /export/backup.zip "Project1" ""

However, that will just return an error message. You need to specify the "Branch". If you want to use the default branch, then you need to specify "HEAD" as the branch name.

Like so:

./exportProject.sh Administrator STC "HEAD" /export/backup.zip "Project1" ""

Then it will work.

When you to the importProject.sh you don't need to specify the "HEAD" though. Strange.