The German book SAP Schnittstellenprogrammierung written by Michael Wegelin and Michael Englbrecht is now also available in English.

As all other aspects of the NetWeaver Portal 7.0, also the collaboration infrastructure can be enhanced by customer specific aspects. Today we want to show you shortly the integration of Twitter into the collaboration infrastructure. To integrate Twitter into your own application, you can find various APIs providing a convenient access to the Twitter API.

The NetWeaver Portal Collaboration infrastructure consists of several aspects like collaboration rooms or the collaboration services. We want to integrate Twitter as a collaboration services. Collaboration services are integrated into the Collaboration Launch Pad (CLP). The CLP can be reached via a link in the Tool Area.

The collaboration launch pad (CLP)

CLP extensions are a bit different to portal components. A CLP extension is some kind of FLEXUI-component, so the initial NWDS project setup is compareable to the FLEXUI-development.
The incredience for creating a CLP-extensions are:

  • Create a Portal Application Project
  • Add the necessary FLEXUI-aspects to the project (e.g. add a RF global service component). As a result the project will have a new folder with the name src.config and some .co.xml files.
  • Add a portal component e.g. of the type DynPage
  • Implement the DynPage
  • Deploy your application
  • Add the newly created extension to the CLP-menu

In the an upcoming blog entry we will show you how to implement a simple Twitter search.

Twitter search UI

Scala meets SAP

Scala is a new programming language for the Java Virtual Machine. In the following we want to demonstrate how to implement a simple Scala-SAP-client. We will implement a Scala application that invokes a remote function that was implemented for our German book SAP-Schnittstellenprogrammierung (the book will also be available in English at the end of 11/2009). The interaction of Scala and Java is seamless at the level of language, but the integration of Scala into the Eclipse IDE is very pure (e.g. there is no code completion for Java classes in the Scala-IDE, so you have to do a full rebuild all the time)

Step 1: After the installation of the Scala-plugin into the Eclipse-IDE   we create a new Scala project and add the SAP JCo-library (available on the SAP Marketplace) to the build path of the project.

Step 2: Implement a scala application to invoke the function module.

object SAPMeetsScala extends Application {
  val sapFacade = new ScalaSAPFacade
  sapFacade.startSAPDemo
}

Step 3: Implement the class ScalaSAPFacade to invoke the function module Z_IFP_CREATE_ORDER.

package scalaeai

import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoStructure;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoTable;
import com.sap.conn.jco.JCoFunction;class ScalaSAPFacade {

  def startSAPDemo {
      val destination = JCoDestinationManager.getDestination("SAPDESTINATION")
      // get the function proxy for the fm Z_IFP_CREATE_ORDER
      val jcoFunctionProxy = destination.getRepository().getFunction("Z_IFP_CREATE_ORDER")
      //retrieve the complete list of metadata definitions for the import parameter

      val jcoImportParameterList = jcoFunctionProxy.getImportParameterList()
      //retrieve the structure for the order header
      val orderHeader = jcoImportParameterList.getStructure("IM_ORDERHEADER")
      //call setValue for the necessary fields
      orderHeader.setValue("XXX","XXX")
      val orderBody = jcoImportParameterList.getTable("TA_ORDERPOS")
      orderBody.appendRow()
      orderBody.setValue("TA_ORDERPOS_MANDT",100)
      // do the same with the rest of the table      
      jcoFunctionProxy.execute(destination);     
      val orderID = jcoFunctionProxy.getExportParameterList().getInt("EX_ORDERID")
      println("Order created with the ID " + orderID)
    }

As you can see, the integration of JCo into Scala is quite simple. The JCO-connection configuration is placed in the file SAPDESTINATION.properties.  As you can see we call the setValue method on the IM_ORDERHEADER structure so set the import parameters for the function module. After the successful invocation of the RFC-module, we read the export parameter EX_ORDERID and print the orderid

Last week I had the privilege to teach BC410 - Development of User Dialogs with Classical Dynpro Technology. In this class a question popped up which can be solved quite easily, if you combine your knowledge of report programming with your knowledge of dynpro programming. The question is:

How can you use select options in classical dynpros?

For reports, i.e. type 1 ABAP programs, the answer is simple and straightforward. Just use the SELECT-OPTIONS statement:

DATA:
  wa_spfli TYPE spfli.
SELECT-OPTIONS:
  so_car FOR wa_spfli-carrid.

This statement in a type 1 ABAP program results in a generated selection screen, dynpro 1000, in which the user can enter complex selection criteria for an airline. But how can you do this for a module pool - an ABAP program of type M - which is used for interactive programs? The solution is quite simple.

First: Create a selection screen in the top include of your module pool:

DATA:
  wa_spfli TYPE spfli.

SELECTION-SCREEN BEGIN OF SCREEN 1001 AS SUBSCREEN.
  SELECT-OPTIONS:
    so_car FOR wa_spfli-carrid.
SELECTION-SCREEN END OF SCREEN 1001.

This generates the selection screen 1001 as a subscreen.

Second: On your dynpro, create a subscreen area (named sub, for example) in which to display the selection screen created in the previous step.

Third: In the screen logic associated with this dynpro, embed the selection screen into the subscreen area by using CALL SUBSCREEN:

PROCESS BEFORE OUTPUT.
  ...
  CALL SUBSCREEN sub USING sy-cprog 1001.

PROCESS AFTER INPUT.
  CALL SUBSCREEN sub.

That’s it. During PAI, you then have access to the select options entered by the user.

The SAP NetWeaver Business Client has been around now for more than a year. So it is not surprising that I get more and more questions concerning this new piece of software: What is it, after all? What can it do? Does it replace the SAPGUI?

What is SAP NetWeaver Business Client?

SAP NetWeaver Business Client (NWBC) is not really a client like SAPGUI or the Web Browser. It merely provides a frame around three different clients: SAPGUI, Internet Explorer, and the new Web Dynpro Smart Client, which is currently being developed by SAP.

NetWeaver Business Client

NetWeaver Business Client

The SAP NWBC basically provides a menu on the top, a navigation area on the left hand side, and a canvas area in the center. Within this canvas area, the SAP NWBC displays the user interface of the currently running application. The application may either be:

  • A classical ABAP Dynpro application. In this case, the application will be rendered by the well-known SAPGUI Windows frontend inside the canvas area.
  • Any HTML application, like for example a Business Server Pages (BSP) application or a ABAP Web Dynpro (ABAP WD) application. In this case, the application will be rendered by Microsoft’s Internet Explorer Control inside the canvas area.

For Web Dynpro applications, there is even a third client which can display this kind of applications within the canvas area of NWBC: The smart client, which is currently being developed. The smart client takes much of the burden from rendering JavaScript and HTML from the Server, and provides a more direct user interface experience than is possible with plain HTML user interfaces, like drag and drop, or soft scrolling. However, the smart client is not yet widely used in the NWBC.

Power Lists and Object Based Navigation

SAP NWBC was first introduced with SAP All in One (SAP A1), SAP’s offering for the mid market. SAP A1 strives to provide much simpler user interfaces than the standard ABAP Dynpro applications do. A new generic ABAP Web Dynpro application, the Power List, was developed by SAP to uniformly display lists of business objects (like e.g. Sales Orders). Indeed, the screenshot above shows just such a Power List. From such a list, the user can select a business object and choose actions like display, edit, or delete. These actions then launch a different application (displayed in the canvas area), to perform the selected action. This is called Object Based Navigation (OBN).

Which applications can be started by the user, and which actions on the Power Lists launch which application is determined by the role menu of the roles the user is assigned to. The roles may either be SAP Enterprise Portal Roles, or SAP NetWeaver Application Server roles created with transaction PFCG. The details of the user menu of the role dictates the structure of the navigation area in the right hand side of NWBC, and the details of OBN.

Why a New Client?

SAP needed this new client in order so solve a problem in SAP All in One:

How can simple User Interfaces based on Power Lists be introduced in SAP A1 without having to rewrite all classical ABAP Dynpro applications? It is clear that SAP cannot rewrite all classical ABAP Dynpro applications, not even only those in SAP A1: They do not have the manpower, and furthermore partners have been using SAP A1 to develop new vertical applications. And these applications are not controlled by SAP.

So NWBC is used to cheat on the users a little bit. It tries to hide the fact that they are really working with two very distinct user interfaces: SAP GUI and the Web Browser. But because the look and feel of the two interfaces differs quite a lot, this will not go unnoticed for a long time. And, because this really is a kind of hack, there are still loads of inconsistencies in the embedding of SAP GUI applications. For example, users can still launch a new external mode in a separate SAPGUI window outside the NWBC canvas by clicking on the appropriate icon in the standard SAPGUI toolbar.

Is this the End of SAPGUI?

No, not for the next five to ten years or so. But with NWBC SAP clearly sets a roadmap for their user interfaces for the years to come:

I suspect that SAP will concentrate more and more on ABAP Web Dynpro than on traditional ABAP Dynpro as a user interface technology. Of course, SAP cannot do this shift within one or two years. The time horizon is more in the region of 5 to 10 years. So SAP needs a vehicle that supports this gradual shift. SAP NWBC is exactly this vehicle. With SAP ERP Enhancement Pack 3, this vehicle is now also available for the users of SAP’s main product.

In the next years, SAP will also put much effort into developing its smart client to render Web Dynpro applications. In the meantime they just embed the Internet Explorer control to do the rendering of those applications.

So SAP NWBC is a strong hint for all ABAP developers out there to pay some attention to ABAP Web Dynpro technology and closely watch, which user interface technology SAP is going to emphasize in the near future.

I don’t know why but during driving back home the headline of this blog came up into my mind. I have to think much more on that topic, to have a clear opinion, but here are my first thoughts:

  • Is it really possible to find metrics to measure the healthiness of a Web Dynpro Java application?

  • Are Web Dynpro applications really large enough to measure, so it is worth to measure?

  • Following the statement of Tom DeMarco “You can’t control what you can’t measure”; the answers of all above questions have to be yes. You can’t measure Web Dynpro by counting the lines of code. That won’t make sense, but the component model and the interpretation in each application can be used to do some measurements. May be also the implementation of some standard Web Dynpro patterns can help to measure the quality.

    So we can measure Web Dynpro by metrics like coupling and cohesion. We can add the CBS-build time as another metric. But what is the indicator of a problematic build time? Is the build time not a different interpretation of the coupling metrics? Is the amount of context mapping relationships a possible metric candidate?

    After finishing thinking on the topic, you will find a Wiki-entry where I will elaborate more on this topic.

Today the AddOn Software Wiki went public. It is intended as a repository for our SAP related technical knowledge which we want to make public. This will shift the focus of this blog away from heavy technical papers to shorter pieces of information and observation.

Michael Englbrecht announced a series of papers on a Web Dynpro Pattern Language some months ago. This is the first area of the Wiki that will be filled with content. Comments are welcome, but please bear in mind that this series of papers is still under heavy construction.

After the usage of Selenium in many standard Java/ JEE and ASP.NET projects, I decided to find out in a real life Web Dynpro for Java Project, how the Selenium could be used to run automated UI-Tests on WDJ.

Selenium (http://selenium.openqa.org) is a test tool for web applications and provides three different flavours to create and run tests. It is heavily used by Google to test their applications.

Selenium flavours are:

- Selenium core

- Selenium IDE

- Selenium Remote Control (short RC)

Selenium core is a JavaScript Framework to write tests for web pages in the Selenese HTML table format. Selenium IDE is a Firefox Add-On to record test scenarios and save them in the same style as the hand written Selenium core tests.

The limitations of the two flavours are:

- that the Selenium core must be installed on the same server as the application

- the expressiveness of the Selenese HTML table format is a little weak.

- You can’t run the tests automatically. So a unit test can’t be executed automatically (e.g. within an Maven or Ant script)

To overcome those limitations Selenium RC is the solution. Selenium RC is a test tool which allows you to write automated web application UI test. It is not limited to Java, it supports many programming languages. Selenium RC comes with a server which automatically launches and kills a browser session. This makes it possible to use e.g. JUnit to write tests against a web application.

The small piece of Java code below shows how to test a simple Web Dynpro application.

Application for the unit test (Figure 1).

Application for the unit test (Figure 1).

public class TestCalculator extends TestCase {

public void setUp() throws Exception {

}

protected void tearDown() throws Exception {

….

}

public void testAddition() throws Throwable {

selenium.open(DEMO_URL);

assertEquals(”Demo”, selenium.getTitle());

selenium.type(”EIDP.DemoCmpView.a”, “12″);

selenium.type(”EIDP.DemoCmpView.b”, “12″);

selenium.click(”EIDP.DemoCmpView.plusbutton”);

selenium.waitForPageToLoad(”5000000″);

assertEquals(”24″, selenium.getValue(”EIDP.DemoCmpView.a1″));

}

}

The test case communicates with the Selenium RC server. The server is responsible for the communication with the NetWeaver J2EE Engine. The last figure shows the successful execution within Eclipse.

Test results in Eclipse (Figure 2).

Test results in Eclipse (Figure 2).

Another interesting thing with Selenium and Web Dynpro is that you will learn a lot about how UI-Elements are rendered.

If you need more information on Selenium in conjunction with Web Dynpro or HTMLB contact me (we also give workshops on how to use unit test frameworks in the SAP NetWeaver Portal and J2EE environment).

The other day we’ve tried to integrate a XFire with BEA based web service infrastructure into Web Dynpro through the Adaptive Web Service (AWS). Everything went fine until we’ve tried to test how stable the handling of application exceptions is done inside AWS. The application exception follows the standard rules of Java exceptions and contains reference to a details class (see Figure 1).

Class diagram (Figure 1).

Class diagram (Figure 1).

The failure was transported as a standard SOAP:Fault with the following anatomy:

HTTP/1.1 500 Internal Server Error
Date: Thu, 18 Jan 2008 14:27:22 GMT
Content-Type: text/xml; charset=UTF-8
Set-Cookie: <value is hidden>
Transfer-Encoding: chunked
Connection: Close 0371

<soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”>
<soap:Body>
<soap:Fault><faultcode>soap:Server</faultcode>
<faultstring>An error occurred Message</faultstring><detail><WsExceptionDetail xmlns=”http://www.xyz.com.”><dump xmlns=”http://namspace.com “>dump</dump><exceptionClassname xmlns=”http:// namspace.com “>classname</exceptionClassname><keyOfError xmlns=”http:// namspace.com “>kurztext</keyOfError><shorttext xmlns=”http:// namspace.com “>short</ shorttext ><details xmlns=”http:// namspace.com “>details</details><timestamp xmlns=”http:// namspace.com “>timestamp</timestamp></WsExceptionDetail></detail></soap:Fault>
</soap:Body></soap:Envelope> 0000

As you can see this is standard as defined in the SOAP-specification. On the Web Dynpro side the error is caught and handled as follows:

try {
// … invocation of the AWS-mode
}
catch(WDWSModelExecuteException e){
trace(wdContext.currentRequest_DoSomethingElement().modelObject(),e);
SOAPFaultException fault = e.getSOAPFault();
// examine the fault-object
}

The trace-method prints the responselog after the invocation.

private void trace(WSTypedModelClassExecutable requestMod, Throwable ex){
wdComponentAPI.getMessageManager().reportException(”response log ” +
requestMod.wdGetResponseLog(),false);
}

With the trace method we check if the response received by the NetWeaver Application server looks identical as the response send from BEA Weblogic.

We thought that the getSOAPFault-method will solve our problem. Unfortunately this is not the case in your situation. The result of getSOAPFault is null-reference. It was not clear how we can influence the processing of the failure handling in WDJ to fill the getSOAPFault-method.

At the end we’ve decided to implement our own stacktrace anlayzer.

public static WsClientExceptionDetail walk(Exception ex) {
if (ex instanceof WDWSModelExecuteException) {
if (ex.getCause() instanceof InvocationTargetException) {
InvocationTargetException _invTargetEx =
(InvocationTargetException) ex.getCause();
if (_invTargetEx.getTargetException() instanceof SOAPFaultException){
WsClientExceptionDetail _clientEx = new WsClientExceptionDetail();
SOAPFaultException _soapFaultEx = (SOAPFaultException)
_invTargetEx.getTargetException();
Detail details = _soapFaultEx.getDetail();
Iterator iter = details.getDetailEntries();
while (iter.hasNext()) {
DetailEntry _detailEntry = (DetailEntry) iter.next();
String value =
_detailEntry.getElementName().getLocalName();
Iterator childIter = _detailEntry.getChildElements();
while (childIter.hasNext()) {
Object _obj = childIter.next();
if (_obj instanceof SOAPElement) {
SOAPElement _soapElement =
(SOAPElement) childIter.next();
// get exception details.
}
}
}
// return exception details
}
}
}
return null;
}

During the last month I often have been discussing with customers and course participants in the SAP J2EE environment, whether it makes sense to have software architectures in place even for their daily development. Most of the time the response was: “Well our project and our team is that small, we do not have time and money to work on architecture”. And another argument often heard was: “The customer will not pay such things”.

From my point of view the last sentence is correct and ok, because customers think that software quality - and for me having a clear architecture is also a indicator of software quality - is an implicit requirement.

To give an analogy from non-IT live:

When buying a car, nobody will stress that reliable workmanship is an extra and therefore you will have to pay extra for this. So I think it would also not be fair to IT customers to make ask for reliable workmanship and deliver crabby products if they don’t.

In addition, having some design principles and architectural decisions will make the life of each developer much easier.

Think, for example, about changes in the requirements. Without a clear architecture you probably will have to tear apart the whole system to accomodate a change of requirement. With a clear architecture, the chances are much higher, that developers can easily identify those few parts that really need to be touched whithout having to moan “Oh dear, how will we be able to integrate this”.

Looking in to the world of the SAP NetWeaver Portal, many business packages are around. A new development approach is to build Portal Components with Web Dynpro technology. Even there, only few people think about having a clear architecture, in order to increase the productivity of the team and the health of the whole application.

Some months ago I thaught a Web Dynpro-class in Denmark. We discussed several architectural issues, like creating a Design Component (DC) for your aRFC-model and reuse this DC in all other Web Dynpro components where necessary. One participant from Sweden told me: “We do not create a single DC. Our external consultants create a model several times in their face full components. So we have several model representations of your backend model!”

I hope, no I am quite sure that everybody will say, that this external consultant not worth his money

So I think I merely write this Blog entry to stress this single point: Have a look at design and software architecture. Have some peer reviews in which a colleague or an outsider to the project has a look on your code. Even if you think your project is way too small. Even if only two people work on a project, there should be a certain level of quality. And beware: Sometimes, software development is like a boomerang. Your code will come back to you.

« Older entries