Vous êtes sur la page 1sur 223

E R P S O F T W A R E

E N G I N E E R I N G

REDHUAN D. OON

ADEMPIERE COMMUNITY

www.adempiere.com

Nahmitzer Damm 32 12277 Berlin Germany • telephone: +49-30-69203854-0 • fax: +49-30-69203854-9


E R P S O F T W A R E
E N G I N E E R I N G

C602 - Asian Executive Master in


Open Source Software ERP

Conquering The World of Industry and Commerce

Nahmitzer Damm 32 12277 Berlin Germany • telephone: +49-30-69203854-0 • fax: +49-30-69203854-9


E R P S O F T W A R E
Study Approach
E N G I N E E R I N G
▪ The mode of study is self research under guidance and discussion. The student is
encouraged to be communicative, sociable, creative, resourceful and critical. Wise non-
conformity is a plus. Publishing or writing one's works and thoughts in the suggested
places and in own original words can give excellent marks.
▪ From day one, the student joins Web 2.0 projects such as the chatroom, blogs, forums,
wikiversity and SourceForge where exposed interactivity can occur with the community at
large. Those who can solicit participation from others are considered successful advocates.
▪ The students are to use heavily the web and to derive source materials for creating their
own pages based on the whole course roadmap which is purposely indicative and not
exhaustive.
▪ The students have to act as a whole team to devise ways to make a better impression to
attract the right attention and build a professional image.

Nahmitzer Damm 32 12277 Berlin Germany • telephone: +49-30-69203854-0 • fax: +49-30-69203854-9


E R P S O F T W A R E
E N G I N E E R I N G
Study Schedule Schema
A. Credit Hour: 3 hours (120 learning hours per semester)
1. Self Independent Study - 42

2. Tutorial / Face-to-Face Interaction - 12

3. Online Interaction - 30
4. Doing Assignments - 18

5. Examination Preparation - 18
B. Teaching Method: Self Independent Study, Tutorial and On-line Participation

C. Assessment Detail:

1. On-line Participation 10%


2. Individual Assignment 10%

3. Case Study/Group Assignment 20%


4. Mid Term Exam 20%

5. Final Examination 40%

Module Topics Schema


This course module comprises of 6 chapters. This student manual is the raw content for the
online e-learning facility under production by Asia e-University.

COPYRIGHT NOTICE:

THIS WORK HAS PARTS DERIVED FROM THE ADEMPIERE COMMUNITY. IT IS


ARRANGED AND AUTHORED BY RED1 FOR ASIA E-UNIVERSITY AND HEREBY
ENTRUSTED ALL CONTENT TO THE CREATIVE COMMONS 3.0 LICENSING.

RED1 - www.red1.org

Nahmitzer Damm 32 12277 Berlin Germany • telephone: +49-30-69203854-0 • fax: +49-30-69203854-9


Table of Contents
MODULE 4 - ERP Software Engineering 1

Chapter 1 - Enterprise Software Crisis 2


Learning Objectives 2
Introduction 3
1.1 What is Software Engineering? 4
1.2 What ERP Needs 7
1.3 Too much integration 13
1.4 Upgrading Complexity 16
1.5 Time To Market 18
1.6 The OpenBravo Story 21
Quiz 23
Glossary 23
Summary 24
References 25

Chapter 2 - Community Software 26


Learning Objectives 26
Introduction 27
2.1 Community Support 28
2.2 Standing on the Shoulders of Giants 30
2.3 Eclipse from IBM 32
2.4 Compiere from Jorg Janke 34
2.5 SpagoBI Business Intelligence Add-On 36
2.6 Ant for Building Scripts 37
2.7 SourceForge.net Project Management 42
2.8 Usability and Stability 47
2.9 ZK Ajax from Low Heng Sin 48
A D e m p i e r e C o m m u n i t y ERP Software Engineering

i
2.10 Private Forking from Anyone Else 52
Quiz 54
Glossary 54
Summary 55
References 56

Chapter 3 - Application Strategy 57


Learning Objectives 57
Introduction 58
3.1 Software Building Strategy 59
3.2 What About OfBiz? 62
3.3 Software Building Model 63
3.4 Rapid Application Framework 68
3.5 E-Ticketing Example 77
3.6 The Callout 81
3.7 Reporting On The Fly 82
3.8 Reusing Patterns 83
3.9 ASP 85
3.10 SaaS Revisited 88
3.11 Service Oriented Architecture 89
3.11a Web Services Security 97
3.12 Status of OpenBravo POS Integration 103
3.13 Cloud Computing 109
3.14 OSGI Plugin Components 110
Summary 122
Quiz 123
Glossary 123
References 124

Chapter 4 - Handling Source 125


Learning Objectives 125
Introduction 126
4.1 Why Java? 127

A D e m p i e r e C o m m u n i t y ERP Software Engineering

ii
4.2 SourceCode Layout 129
4.3 Checking Out Source 130
4.4 Deploying from Source 133
4.5 Persistence Object 136
4.6 Application Dictionary Overview 139
4.7 Application Dictionary Technicals 142
4.8 Query Refactoring 146
Summary 150
Quiz 151
Glossary 151
References 152

Chapter 5 - Modifying ERP 153


Learning Objectives 153
Introduction 154
5.1 Extending ADempiere 155
5.2 Callouts 157
5.3 Callouts (Meta-data) 160
5.4 Rule Script for Process 163
5.5 Customization.jar 166
5.6 Model Validator 170
5.7 2Pack 173
5.8 2Pack Any Table 179
5.9 Example of exporting Payment Terms with 2Pack 180
5.10 Log Migration Script 182
Revision 193
Quiz 199
Glossary 199
Summary 200
References 201

Chapter 6 - Testing 202


Learning Objectives 202

A D e m p i e r e C o m m u n i t y ERP Software Engineering

iii
Introduction 203
Fitnesse Testing Framework 204
Hudson Build Server 205
Logical Bugs 208
JUnit Testing 209
Quiz 212
Glossary 212
Summary 213
References 214

A D e m p i e r e C o m m u n i t y ERP Software Engineering

iv
“It's OK to figure out murder mysteries, but you
shouldn't need to figure out code. You should be
able to read it.”

- Steve McConnell

REFERENCES:

ANTHONY FINKELSTEIN; JEFF KRAMER , (UNDATED PAPER), SOFTWARE ENGINEERING:


A ROADMAP , UNIVERSITY COLLEGE LONDON; IMPERIAL COLLEGE, UK.

JÖRG BECKER, MARTIN KUGELER, MICHAEL ROSEMANN, (SPRINGER 2003). PROCESS


MANAGEMENT

LESZEK MACIASZEK, BRUC LEE LIONG , ADDISON WESLEY (AUGUST 9, 2004),


PRACTICAL SOFTWARE ENGINEERING: A CASE-STUDY APPROACH

WALT SCACCHI, INSTITUTE FOR SOFTWARE RESEARCH, PROCESS MODELS IN


SOFTWARE ENGINEERING, (FEBRUARY 2001 ) UNIVERSITY OF CALIFORNIA, IRVINE

ERIC RAYMOND, THE MAGIC CAULDRON, (1999) HTTP://WWW.CATB.ORG/~ESR/


WRITINGS/MAGIC-CAULDRON/

A D e m p i e r e C o m m u n i t y ERP Software Engineering

v
MODULE 4 - ERP Software Engineering
This module, while introducing the student to the engine and engineering behind the
Open Source ERP, ADempiere application, potrays a landscape of the present issues and
future challenges with ERP software engineering.

Module Outline
This module not only brings the student to the heart of an ERP software such as its
design, sourcecode, and reasonings, but the chaotic wisdom of a mob community in
maintaining and growing it. The ADempiere project is apt due to a living community
been able to carry on what many companies would have spent millions figuring it out.

Learning is fun Graduating is more fun Ultimate fun when your life is fulfilled

Prior Knowledge
This course module assumes basic software engineering hands-on skills including basic
java programming and have followed the 2nd module about setting up ADempiere and
using it.

Module Objectives
1. To appreciate the challenge facing the creation and maintenance of ERP Software
2. To get under the hood of an actual ERP Software
3. To have hands-on capability in handling such software right up to deploying
changes

4. To grasp the importance of a dynamic global community behind a FOSS ERP project

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


Page 1
Chapter 1 - Enterprise Software Crisis

Learning Objectives
By the end of this chapter, the student shall be able to:

1. Further acknowledge the extent of software crisis for Enterprise Software;

2. List the issues facing the development of ERP software;

3. Detail some of the ways such issues are overcome by the ADempiere project.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


Page 2
Introduction
One mental exercise I like to put your minds through before we proceed is this
undisguised analogy:

1. To setup a Linux operating system, you take one hour; To setup an ERP system, you
take one year.

2. If the operating system fails, blame the software; If the ERP system fails, blame the
people.

Software engineering has long be characterised as suffering under a condition of crisis


ever since it was first mentioned by F. L. Bauer at the first NATO Software Engineering
Conference in 1968 at Garmisch, Germany[1].

We can say still see the same condition pervalent today and it is exarberated by the
following factors:

1. The shortage of skillful human capital to manage software applications;

2. The internet revolution continuously changing the technological landscape;

3. The social forces that lead to more afluent demand for near perfect quality in
consuming and expressing preferences.

However the web also bring about some of its medicine besides its poison. The concept
of Web 2.0 where consumers also produce information or human capital in resolving
some of this crisis as proven in the Free and Open Source Movement has brought about
a vast phenomena to producing quality software thus circumventing somewhat the
above-mentioned crisis.

Nevertheless, software engineering is not a layman skill and you can find less advocates
of it then for example to find volunteer editors for wikipedia, the most famous example
of Web 2.0 social phenomena.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


Page 3
1.1 What is Software Engineering?
Firstly we have to ask if it is a science or an art? A science will mean for example,
building a bridge where you can see exactly what is happening and can time precisely
its near completion. You will not enjoy the same visibility with software engineering. It
is still a cottage industry of hand stitchers that will make you wait and wait till the
stichers say its ready[2]. It is somewhat condemned as an archaic art, best known to only
a handful of artisans.

However there is a definition that software engineering is a branch of systems


engineering where that systems engineering itself is the culprit! It is the one that needs
improvement, not software engineering which has matured to a true rocket science. It is
the architecture and design aspects rather than the quality of software platform or
technological prowess behind it. We now have ample memory, CPU speed, internet
reach to achieve anything of colossal size.

Figure 1.1 - Software has its hidden cost from the start

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


Page 4
Managing software development faces tremendous challenges of the need for proper
quality and defect management at the design level rather than the late coding level. The
sheer number of human eyeball-hours cost money to hire. The need to keep going to
ensure software hygiene costs a lot[3]. This inevitably pose a gentle lesson to software
creators to reuse rather than create each artifact anew. Thus the best option open to
them here where they can still put forth their own share of their IP and brand equity is
to do it on other people’s software, namely open source. Or rather to join forces with a
community-based one as an equal 1st class citizen.

In the ADempiere project example, we can see how fast it gain prominence and the ease
of bringing in resources at short notice, but there is a bottle-neck at the software
maintenance or upgrading stage. Deep and experienced brains are needed besides just
mere eyeballs looking out for bugs[4]. Nevertheless, having a volunteer community
around a free open source project alleviates most of this constraint of limited human
brain power in relative competition to proprietary projects.

The advancement of Object-Oriented Programming (OOP) allows component-type


building blocks to make the creation of software as more factory-like and thus more
standardised and predictable. In fact the term ‘standardisation’ is now the buzz word
for the way forward. To take out a defective wheel from a car and fit it with another
wheel is easy because they are of standard sizes and standard bolts. For example they
all have four bolts. If not, we still need not worry, as there are further adaptors to
replace the coupling for the wheel to the right quantity of bolts.

The systems or architectural aspects of software are still been hotly debated and have
yet to become true independant standards. The dominant role of vendors also add to
the chaos as each vendor wishes to brand its own standard against the other
competitors in the market. There are unifying groupings such as OMG (Object
Modelling Group) and WfMC (Workflow Management Coalition) where competing
vendors participate and collaborate with a singular standard, but its implementation
may be proprietary and fast changing due to technological advancements that
shufflings still occur at a fast pace leaving often the standards behind. One example is
during the emergence of e-banking in the mid 1990s, SET was thought to be the
standard agreed upon by the banking system integrators, but SSH gate-crashed into the
marketplace and became the defacto standard for encrypted data transmission sending
SET into oblivion.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


Page 5
Contemporary softwares hailed the namesakes of Java technologies but how will it hold
up now that Sun Microsystems, the creator of Java has fallen and sold to Oracle? Other
language platforms with its own attendant frameworks such as Php, C++, Python,
Groovy, Ruby and even Object C enjoy their own strong and wide appeal among techies
who often embroiled themselves in fierce ‘holy wars’ in defending their own prefered
choice of programming platform.

Many experts have written on a more holistic approach to the crisis. Bernard Boar in his
book “Practical Steps for Aligning Information Technology with Business Strategies:
How to Achieve a Competitive Advantage” (Wiley 1994), painted the way forward with
lots of standardised artifacts or drawings with ready to reuse blank boxes in a more
formalised way, so that architects can design the intricacies with more precise language
and semantics.

Peter Herzum and Oliver Sims, wrote in “Business Component Factory : A


Comprehensive Overview of Component-Based Development for the
Enterprise” (Wiley 1999) on how more standardised framework can be constructed for
operations and document processing in a business environment of which ERP is mainly
about. At the time of its writing, this book predicts that a factory of ready made
components which can be easily picked and assembled into a new application would be
ready in 10 years time, which is now!

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


Page 6
1.2 What ERP Needs
In refering to the ADempiere project that is part of the family of Compiere Open Source
ERP together with OpenBravo that also forked into its own project, we can gather alot
of understanding on what ERP software is about. The context and challenges it faces are
huge as ERP concerns the complete picture of business flows and data manipulation
within any organisation on a single platform.

The right way of understanding a software is to understand not only what it is needed
for but how it has to be done. ERP has to follow these constraints and requirements:

1. It has to do sound accounting transactions that are approved by auditors;

2. It has to cover numerous departments of different roles within an organisation;

3. It has to cover numerous roles of users with different access authority;

4. It has to carry processes and data across departments to satisfy different users;

5. It has to be responsive when accessing volumious data including archived ones


of previous years;

6. It has to present data in very well formated user-friendly tone and design;

7. It has to be secured from fraudulent practice and traceable to source documents;

8. It has to interface with latest web technologies and external 3rd party
applications;

9. It has to be able to operate on different computers with different operating


systems;

10. It has to follow design of business and operational rules governing its data
from different authorities be they internal, external or regulatory;

11. It has to allow changes to its behaviour or model constantly or periodically as


the case may be.

The early Compiere project has established a clear defnition of the model that it is using
in its ERP application when it first debuts in 1999, about ten years ago. It recognises that
an ERP application has to interface with its users along a standard presentation and

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


Page 7
design. The following diagram attempts to give some sense of what that design is made
of and how it organises itself.

Figure 1.2 - Compiere’s Application Interface Design

From the above design we can deduce its underlying complexity of sourcecode
packages and model requirements. There will be an elaborate array of data models to
capture the properties of this design and processes to facilititate its functions.

This Compiere design particularly includes an Application Data Model comprising of


Window, Tab and Field framework where each Tab is associated with a single actual
data table within the ES. Each column in turn is associated with properties such as
DataType, Reference lookups, and Callout processes. Essentially this is a nice and robust
application design where you can have:

1. A data model with its properties, and a

2. A process that acts upon each field value within that model.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


Page 8
The rest of the application merely interface such information and processes to the
comprehension and control by the end-user. The following diagram illustrate this
understanding further in a conceptual but detailed specific terminology, understood by
the open source applications (Compiere, OpenBravo, ADempiere and possibly others).
Figure 1.3 - Achieving a Modular Design

This progammatical capability of the field is happening at the application layer and not
at the business or functional layer handling business processes such as Sales Order,
Inventory movement or accounts posting. In other words the above is related to the
layer managing the application. From there you can see that it is demarcating the whole
application into clearly defined areas of focus. The Menu View addresses the

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


Page 9
application model directly where its Table-Column structure or Data Model is defined
for every model in the ERP system.

Such a design allow fast prototyping or changes to the application. For example any
new data model can be added at the stipulated area. A new process can be attached to a
column. For more sophisticated new vertical to be added onto this ERP horizontal, we
can create a new document type with its own document process without concern about
the sourcecode scaffolding.

This above diagram (figure 1.2) showing the Application Data Model (described in the
2nd course module on ERP Application Setup) is based on meta-data so that any
changes to the model is done without changes to sourcecode.

Understanding how this application software is designed allows a developer or ERP


architect to think at a higher level when designing a module that fulfills a certain
industry needs. Any module requirement out there can be analysed along the stated
attributes of data model and process. The rest are just input and output formats. The
whole application suite will absorb the vertical module easily and give it the benefit of
standard CRUD and application behaviour like the rest of the ERP horizontal. You can
say that we can easily introduce the new module as a 1st class citizen into the ERP
system. Below is a diagram depicting a conceptual entry of a new module.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 10
Figure 1.4 - Adding New Model to ERP Suite

The new module is incorporated via the Application Dictionary to define the new
model of tables and fields, and its properties. The new model can be transfered to a new
client via XML files such as using ADCK contributed by Trifon Trifonov from Bulgaria.
It can also be transfered via 2Pack exporter/importer contributed by Robert Klein of
USA. The legacy data of this module if any can be imported into the ERP via import
loaders. In later chapters we will go through the mechanics of how the migration of the
new model is done.

What about the disadvantage of such a framework described above? What I can think of
at the moment is that the user interface is a bit limited and rigid and not as aesthetic as
other software (see figure below). There are only 2 columns per row for single record
display and each Tab for each window does not have box panels or embedded panels
besides the normal roll down groups of data columns.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 11
Figure 1.5 - Standard Compiere Window Tab Interface

This Order Window above shows two tabs, Order and OrderLine. The later is for detail
transactions where each one will describe the product and its quantity ordered. Each
line may carry a pricing information too. Other matters such as commission, discounts,
and tax are often included.

As can be seen from the main Order tab, it is quite elaborate and cluttered. Many of
these fields may not be needed and can be removed easily via the SystemAdmin
application dictionary windows such as via the Table & Column window.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 12
1.3 Too much integration
One big need that I intentionally leave out in the earlier section so that we can discuss
this more specifically is the need to have the ERP application covering all of the above
in a single application suite. In other words, all these together with all the functional
modules have to be integrated. As stated, ADempiere inherited its codebase from
Compiere which is mainly Java with lots of SQL scripts and some XML usage.

CC CC
Code Data
Component Object
CC DO DO
SIMPLE CC
DO
DO

COMPLEX

Figure 1.6 - Comparison between simple and complex software

As ERP is a complex system of many components of business processes interacting or


acting upon many items of data objects, it will become very unwieldy to manage[5]. It
requires good architecture and this is what I would prefer to think of as a Software
Engineering challenge for simplicity sake. This is because participants or developers in
the project often discuss software flavours, advancements, framework more than ERP
systems when it comes to thinking about bringing the software forward or to the next
level. One popular discussion topic is about the use of Hibernate or removal of SQL
scripts entirely from our codebase so as to achieve more cleaner separation with the
database layer, and also database independence. But without looking first at the
monstrous size of the whole application, it sounds childish to think about changing it.

The motivation behind all this is the quest for simplicity. The cause is having too much
integrated into the codebase in the first place. The more powerful an ERP system the
more software features are built into it. Many of them are built from the ground up
together with the framework of the application. As such they are tightly coupled and
work in concert as a single application. This would make it bulky and unwieldy to

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 13
maintain or migrate. The learning curve to master its ins and outs will be rather long . I
would estimate it to be about 6 months for a mid-skill programmer.

Why we are concerned about the sheer size (about 3.4 million lines of code for
ADempiere) is the constraints when it comes to maintaining it. Software will always
need to be maintained and changed from time to time if not day to day. There are many
business logic that are still too generic or too specific and whenever a change is
proposed it may affect other aspects of the sourcecode or funtionality.

The period of which Compiere was first written is speculated to be around the late
1990s when Java frameworks has yet to reach a higher maturity as it has today. Today
developers who combed its sourcecode complained that it is not efficient to maintain
and is not scalable and some even claimed that it is not 3-tier. However its main
strength remains to be its abundance of features and unique combinations of tools that
makes it a full fledge ERP solution of subtantial market quality and appeal. Some even
claimed that Compiere can rival SAP B1, Navision, or Oracle Financials.

Among the features inbuilt into the Compiere family of ERP software are:

1. Java code execution tracing logger

2. Multiple localisation features such as translation and currency

3. Application Dictionary modeling and interface

4. Dual automatic user interface for both Java client and HTML client

5. Workflow engine

6. Printformat engine

7. Document type and sequencing engine

8. Accounts posting engine

9. Scheduler engine

10. Persistence Object mechanism

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 14
For those who have worked through the codebase and became familiar with it also
appreciate some good practice in its coding approach:

1. Good separation of classes according to packages and functions such as M classes for
model activity, AD classes for application dictionary level activity and X classes for
model persistence activity;

2. Good ApiDoc commenting;

3. A high standard of code factoring;

4. Usage of famous patterns such as factory and value object patterns;

5. Complete utilities to manage sourcecode compilation and application deployment.

One principle to follow in large complex mass of software components is to employ


loose coupling between components and open standards which will be the case by
using the OSGI framework. ADempiere has undergone such proof of concept and the
community has decided to pursue this option as its future roadmap of adding on
functional modules to its codebase.

Ever since the Compiere project was forked by the community into ADempiere in
September 2006, countless amount of minute changes have also occured:

1. Bug fixes ranging from the very critical security level to minor typo mistakes;

2. Enhancements of present features to cover more common business practice;

3. Extensions into newer technologies;

4. Integration to 3rd party FOSS tools and utilities;

5. Better documentation of operating the application in the wiki

6. Documenting in changed or new classes of the tracker reference in project repository


in SourceForge;

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 15
7. Versioning of sourcecode releases in the repository;

8. Usage of data model migration scripts to allow users to be up to date constantly

9. Branching of modules to better maintain stability

1.4 Upgrading Complexity


Now the whole story becomes more complex because you need to upgrade the software
from time to time. Today people are talking about the latest buzz such as:

1. n-tier architecture for scalability

2. Ajax’s cool html user interface that makes the web page looks amazing

3. Database independence so that the system can run on any database

4. Web services where any 3rd party system can talk to any other system

5. Integration to business intelligence tools such as JasperReports, Pentaho, SpagoBI,


and Palo.

6. Extensibility via ModelValidator, more open Callouts, JSR 233 open scripting and
OSGI componentisation.

The good news is that ADempiere has achieved many of the above except for true n-tier
architecture. About database independence we manage to port to PostgreSQL and
IBM’s DB2 free edition. PostgreSQL is open source and free-licensed which is good
enough for the community. Previously Compiere as locked to Oracle’s database which
became one of the bad points of the Open Source ERP project. During the effort of
making ADempiere talk to PostgreSQL, much embedded codings that are Oracle
specific or of a certain SQL standard are been converted to more open and standardised
formats. This means that ADempiere has made one major jump to be more agnostic to
database flavours.

The most exciting thing to come out recently as announced in the 2nd Berlin Conference
in June 2009 is that Joerg Viola of Object Code GMBH, has succesfully implemented a
pluggable regime into ADempiere sourcecode using Eclipse’s Equinox that follows the
OSGI framework. However while attempting to integrate Libero Manufacturing with
Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering
P a g e 16
Trifon Trifonov and me myself as observers in his Luenen office nearby Dortmund, he
discovered that Libero does not synch well with the classloading mechanism of the
plugin. He told us that it can be done but a lot more proving and testing will be needed.
He gave some idea that it may take someone like him a full one month to resolve the
plugin mechanism to fit into ADempiere. This is an example of how exciting new
technology is fine but not so when attempting to integrate to a ready made monster
such as ADempiere. More work is always needed to move forward.

One way to make future integration a lesser hassle than it is, is to upgrade the software
right now with better coding practice. We have started to introduce substantial changes
to the coding patterns and upgrade management such as:

1. Giving every X_Setter/Getter class an Interface class to refer to;

2. Implementing new Query class that removes SQL scripts from Model classes;

3. Ideal migration path by logging all DB meta-data changes and numbering them;

4. Having centralised ID management for model sequencing to prevent integration


nightmare when similar ID tables showed up from separate 3rd party integrators;

5. Refactoring redundant methods particularly for the new Ajax Web UI mostly done by
Low Heng Sin of Malaysia;

6. Ensuring extension of model behaviour is done at the ModelValidator extensions and


not at the core Model classes to avoid module conflicts.

At the same time, technical improvements are not the bulk of the game. In fact the bulk
of the challenge is having good visibility of the project such as good release
documentation. That we have done by publishing in http://www.adempiere.com/
index.php/Category:Release. By having good documentation, other developers and
more newer ones can follow its progress rather easily and participate further.

Taking this challenge of been visible a bit further, the main crisis with software
development and maintenance over time is that if it is proprietary, it will be largely
invisible to a non-paying community. In doing so, it will have to incur tremendous cost
in fixing or responding to technological changes in the market. We can now see the
proof of this theory in the ADempiere project itself. Every bug fix is freely done and cost
Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering
P a g e 17
nothing to the project. But it will cost a lot of hours of developers’ time if they are
employed by us.

Now one catchy idea looming in the horizon over this cumbersome complexity is the
technology to provide ERP Software as a service (SaaS) rather than inhouse deployed.
This indeed can save alot of time but again there are killer issues with end-users.
Among them are:

1. Security of database. End-users are worried about fraud occuring from the outside
and they cannot control it as their private data is sitting somewhere in the world and
not at their premises.

2. Responsiveness to change. Again being very complex, ERP will need to adapt to
changes with alot of effort. Having it at a remote site with remote experts may not
help cut such a cost down.

ERP is too complex for SaaS[6] and have to be broken down to simpler stacks for specific
business functions and for very small businesses that do not mind exposing their data
to danger. An SaaS can address the above stated issue by giving local repository of the
client’s data instead of having it at the data centre which acts only a backup and should
be encrpted to protect it.

1.5 Time To Market


The scenario dictating software adoption today is one of speed and expediency. The
market has matured to look at ready-made software solutions of the shelf where
possible. Projects which stretch over many months or years are beginning to draw
distaste as the market is getting acustomed to hearing high value solutions at non-
licensed costs. There is always a choice to select from in many cases.

Open source software has removed the goal posts in the game to present options to a
global market. Allowing end-users to adopt, adapt and improvise will mean an upward
path of progress where software becomes better as the need to reinvent the wheel began
to minimise over time. Open source allows solutions to converge, as no code hiding are
preventing them from sharing and consolidating repetitive functionalities.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 18
Applications can then be added or stacked on top of each other. For example there is
now the commonly known LAMP stack which stands for Linux, Apache, MySQL and
Php. This LAMP acronym presents to the market a more united stand that software that
is open will not exclusivate others but work better together.

Since no software solution is perfect match for general users, or perfect fitting ones are
too exhorbitant in pricing, more generic ones that are open to modification will become
more attractive. There will be software that are highly configurable with good
interoperatibility. Proprietary applications are finding it hard to do all this as it dilutes
their patent or control over intellectual property. They either market their products in
terms of services or produce more niche products that are not easily duplicated by open
source. The chances are whatever proprietary vendors can produce, there are almost
equivalent open source and free ones. Though this may put a strain on software
vendors it provides the market more choice and freedom to examine competing
products out there.

The era of Web 2.0 is making or pushing software development more to the public or
community of end-users who may not pay directly to the FOSS vendors but indirectly
support the projects via user review, bug reports and remedies and code contributions
and enhancements. The ADempiere project is a perfect example where there is no
proprietary vendor owning it directly except an open community of users, system
integrators and independent software vendors providing continuity and growth. We
shall examine more of how open source could be finally resolving the software crisis
and may push software engineering to a whole new level outside the walls of expert
developers into the hands of an army of lay users who may bring about better quality in
the end. As Linus Torvalds is said to have said, “More eyeballs make any bug shallow”.

Useful Quotes
The following are famous selected quotes that can provide much wisdom and some
insight, besides needed humour into the challenge of modern software engineering
projects.

1. Brooks Law: "Adding manpower to a late software project makes it later!"

2. “Standards are always out of date. That’s what makes them standards.” – Alan
Bennett
Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering
P a g e 19
3. “Looking at code you wrote more than two weeks ago is like looking at code you
are seeing for the first time.” – Dan Hurvitz

4. “Less than 10% of the code has to do with the ostensible purpose of the system; the
rest deals with input-output, data validation, data structure maintenance, and
other housekeeping.” – Mary Shaw

5. “When you are stuck in a traffic jam with a Porsche, all you do is burn more gas in
idle. Scalability is about building wider roads, not about building faster cars.” –
Steve Swartz

6. “Everyone by now presumably knows about the danger of premature optimization.


I think we should be just as worried about premature design — designing too early
what a program should do.” – Paul Graham

7. “Today, most software exists, not to solve a problem, but to interface with other
software.” – IO Angell

8. “As a rule, software systems do not work well until they have been used, and have
failed repeatedly, in real applications.” – Dave Parnas

9. “When debugging, novices insert corrective code; experts remove defective code.” –
Richard Pattis

10. The bearing of a child takes nine months, no matter how many women are
assigned. Many software tasks have this characteristic because of the sequential
nature of debugging. - Fred Brooks

11. The belief that complex systems require armies of designers and programmers is
wrong. A system that is not understood in its entirety, or at least to a significant
degree of detail by a single individual, should probably not be built. - Niklaus Wirt

12. Design and programming are human activities; forget that and all is lost. - Bjarne
Stroustrup

13. Up to a point, it is better to just let the snags [bugs] be there than to spend such
time in design that there are none. - Alan M. Turing

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 20
14. I have always found that plans are useless, but planning is indispensable. - Dwight
Eisenhower

15. If you cannot grok the overall structure of a program while taking a shower, you
are not ready to code it. - Richard Pattis

1.6 The OpenBravo Story


This is a classic story of Reinventing the Software Crisis. As told above, the whole idea
of open source communal approach to software building is to do away with the high
and terrible cost of maintaining a software project. What OpenBravo did was a
marvelous sin in two parts:

1. Firstly they forked a project in reverse. Well, forks are in fact alright but they have to
be built upon, improving on what good is done, usually incrementally. In OpenBravo
case, they studied the limitations of Compiere and using own resources, did a huge
reverse-engineering of it and announced their own project as if it is their own almost
entirely by virtue of declaring that they did 90% of the fresh coding. This is not paying
homage to the true values they forked from as pointed out by Oleg Gryb (2007) in his
white paper[7].

2. They did not ride on the community. By being an entirely new commercial project,
they tried to form a new community on their own accord. This is not continuing the
roots that were already there. What ADempiere did was to continue from the
Compiere community, addressing their concerns and decide on a collective basis
without commercial considerations.

This is what OpenBravo did in early 2006 a few months before ADempiere was born. It
was financed by a 3rd party, which of course will exact venture capitalistic returns of
about say 25% per annum on their investments. It is reputed to have taken on in excess
of 10 million euros in fundings! Now that is a big debt to repay. This will mean eventual
closing of some selective parts of their codings for direct royalty arrangements that they
will impose on the free market. This immediately put them at a disadvantage vis-a-vis
an unabatedly free one such as ADempiere.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 21
What OpenBravo should do is to place very minimal financing, and leave the rest to the
community out there. The community as demonstrated eventually by ADempiere, will
bring about free testing, free marketing, free support and most of all, free contributions.
All these cost a lot to go on your own, running into millions over a year.

Nevertheless, OpenBravo in its website and forums, also did try to engage the
community by offering more freedom and acknowledgement of contributions done by
outsiders. Still it did not win complete trust from the community. Those who eventually
did join in did not find substantial activity from the rest. Most were dependent on the
said commercial entity to get things going. This proves that open source communal
spirit is like a fragile but evolutionary plant. It will grow, but it takes a true surrounding
of natural ingredients only a self-learned untouched community can provide.

In ADempiere there are lots of complaints about its non-corporatedness or unofficial


way of doing things. There were open flames and fierce disputes over simple things
such as choosing what should be part or not of the trunk. But still, the flames will die
down and the community and project survives and thrives on as if by magic. All this
while, without a single cent of direct commercial ownership and thus there is no payroll
to keep, rent or bills to pay for the ADempiere project. It is akin to the story of the
Taliban army versus the paid US army. In the end, we hear of a high bill running into
trillions of dollars but for the Taliban, not only is there no budget, there is also no
central command system to pinpoint and destroy. In spite of the never ending suicidal
deaths on the Taliban side, it is now reported by US sources to have expanded to 80
countries, with more fanatical members joining on their own accord without promotion.

In a way this is like a misfitful religious phenomena when it comes to describing the
community project. But then would anyone have a better idea to address the software
crisis? Do you have a better idea on how to setup a top notched, highly active, global
software development team that is 24 by 7 and works seemingly without pay?

1.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 22
Quiz
1. State the reasons why there is a software crisis.

2. Why is ERP software the most complex?

3. How does the ADempiere project alleviate us from such a crisis?

Glossary

Term Description

Software Crisis A term to describe the eternal situation facing software


development

Vendor Driven A progress or technology being controlled or defined by vendors


rather than open and public standards

ERP System Enterprise Resource Planning software for business environment

Architecture A technical reference model for a software to follow and build on

ADempiere An open source project forked from Compiere due to the later
closing up certain source from free access and download

Modularization Making software into smaller components that can fit into each
other in a standard fashion easily

Integrated Where a function can lead to another function or access another


data model within the same application

n-Tier an architecture that allows each layer of the software to operate in


a different machine, beyond the 3-tier

3-tier a 3-tier architecture where the database can exist in one server
and the application service in another, leaving the web interface
operating its own logic at the client side.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 23
Summary
1. Software is experiencing an even more elevated sense of crisis due to more
technological advances that rely more and more on software when the expertise to
develop and maintain them at the present status quo does not drastically change.

2. An open source community can resolve many issues in maintaining and expanding a
complex software such as an ERP application.

3. The ADempiere project has many ideas working with other available technologies to
provide better options to reduce the costs of adopting FOSS ERP.

4. An ERP application is unlike Linux in that it requires human intervention to


determine the large scope of requirements for an organisation wishing to use it.

5. For an ERP it is more important to have full functionality than technical


advancements.

6. An ERP system needs to be componentised for easy integration with verticals from
various differentiated industries.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 24
References
1. http://en.wikipedia.org/wiki/Software_crisis

2. http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0000D8

3. http://www.stevemcconnell.com/articles/art04.htm

4. http://analystinfromthecold.wordpress.com/2009/03/06/there%E2%80%99s-a-new-
erp-survey-in-town/

5. http://knowledge.wpcarey.asu.edu/article.cfm?articleid=1378

6. http://searchcio-midmarket.techtarget.com/tip/0,289483,sid183_gci1298568,00.html

7. http://oleg.internetkeep.net/soapiere/SoapiereWhitePapers.html

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 25
Chapter 2 - Community Software

Learning Objectives
By the end of this chapter, the student shall be able to:

1. Detail the ways a community can support an ERP software well;

2. Explain how some FOSS tools are important and useful;

3. Describe how SourceForge.net facilitate FOSS development;

4. Put forward the next idea in business applications for FOSS ERP.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 26
Introduction
The first module on Web Economy described at length how the social engineering
power of a community in the internet environment can bring software projects to a
higher plane of quality and growth. In this 2nd chapter of the 4th module we shall
examine more precisely the manner and the tools that are used towards that.

We can see that there are countless facilities, activities, forces and trends that is bringing
open source to the fore. We can also see that even proprietary players such as Microsoft,
Oracle, IBM, Apple, Sun (now bought by Oracle), Netscape (now gone) and Google are
embracing open source without question. It is only the manner they adopt it that is abit
different due to numerous strategies each player is attempting to maneuvour the
playing field to their advantage if possible. However the long term trend is that all such
maneuvouring will not offer an advantage for long. In the end it seems that an
endowed community will benefit the most. It is almost certainly an end-user market.
Information cannot be hidden and someone is bound to reveal the next best thing - free
and open.

Big vendors are putting more computing power and tools and freedom into the hands
of lay users. The tools are getting more easier and faster to use. Today many who
claimed to be hackers are not really hackers. They are just ‘clickers’! They merely are
good at clicking to download ready-made tools to hack or giving them the perception
that they are good at it, when in fact its the marvelous tools that give them such power
and capability. Nevertheless for ERP software, the eco-system is beginning to emerge
where more end-users who otherwise are not capable of contemplating such software
are downloading and configuring it for their specific use. This is particularly true for
small or low end ERP users such as very small enterprise or industry.

This lower the bar of entry for the whole user chain. Higher level lay users are now
more encouraged to experiment with FOSS ERP and this in turn set their expectations to
drive down or reconsider present expensive engagements with proprietary vendors.
The software also experiences a quantum leap in quality when there is true, open and
unabated peer review that hammers it constantly and persistently.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 27
2.1 Community Support
When software such as ADempiere seems to grow pretty well without its sourcecode
been sold, it is due to the presence of a robust and thriving global community. It is not
just its social presence, but the tools that exist to accomodate its organisational activity
in a completely virtual manner. Applications such as chatroom to synchronising of a
centralised repository at SourceForge.net allow the social experiment to persist and
progress rather smoothly without abating. SourceForge.net for now act as a pivotal
reference point for community members to congregate and discuss in its project forums.
The trackers allow for peer review and submission of bug reports through to fixes and
commits to trunk. SourceForge.net itself is undergoing upgrades to improve its free
services in letting communities scale further without limitations.

The ADempiere community consists of a right and healthy mix of technical and domain
experts such as accountants, business process managers, consultants, integrators,
testers, end-users, developers and salespeople. Quite a number of them are exposed to
or have implemented other vendor products such as SAP, Oracle Financials, Great
Plains, JD Edwards, Baans and also open source ones such as from our parent project
Compiere and our sister fork Open Bravo. Their chatter and interaction ensures a rich
continous stream of information that is both factual, up-to-date or at least fair enough to
avoid the project of veering to an irrelevant path. Issues or resolutions made by the
community are often on track such as to determine the way forward in scaling up its
growing functional modules. Where there are more lurkers or free riders who did not
contribute anything, there will be a relative fraction of sufficient supporters who
manage to contribute good enough for the project to move on. There are numerous
releases, each of which can boast of tremendous amount of bug fixes, new features and
stablisation effort been put into the release.

Since forking, ADempiere has undergone the following releases (in reverse
chronological order):

* Release 353a developmental version December 21, 2008

* Release 342 stable version December 20, 2008

* Release 352a Libero stabilising (alpha) June, 29th, 2008

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 28
* Release 351a Libero Release (alpha) May 31st, 2008

* Release 340s Emily Release March 26th, 2008

* Release 331b December 5th, 2007

* Release 330 Victoria Release July 16th,, 2007

* Release 320 Mayday Release May 1st, 2007

* Release 316 April 2nd, 2007

* Release 315 February 28th, 2007

* Release 314 January 24th, 2007

* Release 313 December 27th, 2006

* Release 312 December 16th, 2006

* Release 311 November 13th, 2006

* Release 310 October 13th, 2006

Besides the above, there is daily or nightly build release onto a live test site - http://
www.testadempiere.com/webui/ as well as a Hudson compilation and quality
assurance server managed by Metas in Bonn, Germany, that monitors every code
commit done to the trunk to ensure it will compile without error. This makes sure that
the sorucecode is always accesible for a clean release anytime.

There are virtual machine releases too that let users setup ADempiere almost hassle free
and within a matter of minutes rather than days and not uncommon failures by many
newbies.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 29
2.2 Standing on the Shoulders of Giants
The greatest effect from and around a well supported open source project is that any
improvement done is not a reinvention of a wheel but a rung higher than what has been
achieved before. Every contribution is like a dwarf that stood on the shoulders of the
giants before so that the dwarf can see further. This cumulative effect often creating a
sum larger than what individuals can do is now inevitable as the web is the perfect
ocean for it[1]. Even if a 3rd party open source software is not directly used in the
ADempiere project, its lessons, tricks or ideas are adopted. Examples are Druid for the
XML2AD and ADCK tools created by Marco Lombardo and Trifon Trifonov repectively;
Eclipse for handling sourcecode and using its plugin utilities such as for database
access, testing, and code debugging and commit. Now, Eclipse Equinox is been used to
convert modules into OSGI plugins.

Far off projects such as OfBiz and the Spring Framework supply ideas on what could be
done in order to scale ADempiere properly. Some interim step done by Trifon was to
introduce interface class for every setter/getter class. A few other senior developers
from Mexico, Malaysia and Romania began to experiment query classes to remove
SQL scripts from the model classes. Such steps move ADempiere closer to better
refactoring. ADempiere is very bulky with alot of ERP functionality and thus migrating
it to any latest platform is very difficult. Ideas such as trying to make it compatible to
Hibernate or Spring in order for it to be more scalable, modular and manageable in its
growth are mind-boggling until the OSGI idea was made feasible by Joerg Viola of
Germany.

The most exciting shoulders to stand on are those of the business intelligence toolsets.
Software such as Drupal, Pentaho, SpagoBI, and Palo are truly amazing and have been
integrated by independant vendors around ADempiere. Even though some of the
scripting or codes have not made into the codebase awaiting readiness from those
vendors, it is no longer a rocket science to make such things happen. Documentation is
abound of such attempts in the project wiki and forums as well as guides from the
respective vendors that any independent developer can follow the footsteps without too
much difficulty. With grander BI capabilities from a growing slew of FOSS applications,
the roadmap for FOSS ERP looks set to head up the value chain as a very sophisticated
and powerful application suite.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 30
The path seems never-ending as magical tools such as Talend, another open source
project for integrating with legacy systems and data are available to remove any last-
mile show-stopper for ADempiere to work or inter-operate in any legacy environment.
This means that an investment of effort into ADempiere cannot be entirely risky as any
previous and external system can be made to talk to it using such a tool. All the above
stated tools have been demonstrated in the 2nd Berlin Conference in June 2009.

Thus it is this twin charge of community and open source shoulder standing feat that
pushes the envelope further and further each day. Even though it is mind-boggling to
imagine how exactly to manage such a geomatrically growing project, the disruptive
but progressive nature of the web and its treasures are making it grow well some way
or the other.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 31
2.3 Eclipse from IBM
One favourite tool developers use is an Integrated Development Environment (IDE)
software called Eclipse (www.eclipse.org). It was contributed by IBM to its initial
sourcecode and support. IBM has invested some USD40 million and released it to open
source in November 2001, seemingly to make it reach a level of ubiquity for creating an
eco-system also for IBM products besides branding for IBM’s services. In a way Eclipse
has reached number one spot but strangely it cannot break out of the pack of other
equivalent FOSS applications in its category cleanly. NetBeans from Sun is still a
favourite with many even though it may be in 2nd spot after Eclipse. There are still stuff
that NetBeans has that Eclipse does not possess such as powerful GUI creation
capability and a perception of stronger technicals under its hood[2].

Eclipse like NetBeans has many addons or plugins that create a massive functional
environment to develop and manage software particularly in a global and remotely
connected manner. This is so important for a community open source project such as
ADempiere where many developers and even users can track changes by updating their
source from the project trunk via Eclipse’s Subversion (SVN) toolset. SVN can apply
only the changes since the last update to a local source. A developer can then examine
the exact changes by comparing it chronologically. SVN is not developed by Eclipse but
another 3rd party open source project and so to get that feature you have to go get it
from Subclipse (http://subclipse.tigris.org/).
Figure 2.1 - Eclipse SVN for checking out code from SourceForge project

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 32
Following instructions that are readily available online from Google is quick and
efficient. Been also open source guarantees that using SVN is not a lonely affair too.

Figure 2.2 - Updating local sourcecode with changes from repository

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 33
2.4 Compiere from Jorg Janke
Of course! The ADempiere project is a fork of Compiere (www.compiere.com) but in
this most important context we stood on this giant’s shoulders. When we first forked,
100% of ADempiere was Compiere. Not only that, its brilliant Application Dictionary
framework, its codebase packaging and structure, countless SQLs for business
reporting, ready-made generators for reporting, workflows and document processings,
accounts posting framework and html interfaces for e-commerce and CRM (customer
relationship management) all allow the project to have continuity, maintaining the
inherited business value and our members circle of dependant clients and users.

While the jury is still out on the debate of whether Compiere did the right thing by
closing some parts and alienating the free-rider community, philosophically or
commercially, it has dropped from the SourceForge rankings even to the other fork,
OpenBravo which is based in Spain and is also commercially-run. ADempiere and
OpenBravo (www.openbravo.com) seem to share the top rankings since end 2006 all
thanks to what Compiere has done as an open source project. Even after forking we still
refer to certain improvements in Compiere to bring over to ADempiere. We of course
still maintain most credit and copyright statements as belonging to Compiere. We also
send patches back to Compiere for its own decision to use them and they did make use
of one very important security hole patch we discovered.
Figure 2.3 - Compiere’s website look - very commercially attractive

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 34
Indirectly ADempiere learnt from its closest neighbours including OpenBravo by
reviewing its antics in commercialising its project, as we now possess hindsight of what
happens to others that has gone before us. Some OpenBravo users eventually migrate to
ADempiere and they bring tales and stories of how it was like there and why they came
over. Many cite the commercial licensing cap over some of its codebase functionality
and most importantly how it could not compete in maintaining the growing demand
for quality and bug free software. Many bug reports went unfixed, as a sizable
developer community did not and could not build up around a commercial-linked
project when there exist a truly non-commercial one. The community prefers a
community-led project over a commercially-led one.

OpenBravo hires around a hundred developers and even that is insufficient to bring the
project to a speed the world demands of. Paid developers require return on investment
by the funders to the company behind the project. For ADempiere where there is not a
single directly paid developer as there is no company that owns it, there are thus no
debts to repay and no report card to fail. The many developers that worked around
ADempiere are either doing it for their own commercial instances or have an itch to
scratch. This somewhat created a gift economy where like a public place, everyone chips
in a bit to keep it well run without feeling the pinch.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 35
2.5 SpagoBI Business Intelligence Add-On
SpagoBI (www.spagobi.org) is an open source business intelligence (BI) toolset that can
be added onto ADempiere to provide a high level or analytical reporting of ERP
information and transactions. A writeup describing how to use it on ADempiere is
contributed by a member of the community from Italy, Andrea Niccolini[3].

The SpagoBI project is a very appealing as business intelligence is a high-value add-on


for any ERP system. Being open source means that the two projects can now work
together to create a more powerful suite to many end-users.

Figure 2.4 - SpagoBI brings ERP performance to the next level

SpagoBI is said to be a middleware that is also open to work with other BI tools such as
the now emerging Palo.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 36
2.6 Ant for Building Scripts
Apache Ant may be small as in its namesake, and often forgotten in the hall of fame list,
but it is big at the simplest level - building scripts. It is a software tool for automating
software build processes. In the Compiere family, it is extremely useful to compile and
package the ERP software for deployment at the server or client level. Ant will seek for
the build.xml file and execute its contents. Below are some important build files in the
ADempiere project.
Figure 2.5 - Build.xml of Utils_Dev (cont’d next pages)

<!-- ================================================ -->


<!-- Adempiere Build -->
<!-- ================================================ -->
<!-- $Header: /cvs/adempiere/utils_dev/build.xml,v 1.4 2006/10/12 00:03:11 jjanke Exp $ -->
<project name="adempiere" default="complete" basedir="../">
<description>
This buildfile is used to build the Adempiere system.
</description>
<!-- set global properties for this build -->
<!--<property environment="env"/>-->
<import file="./properties.xml"/>
<property name="src" value="src"/>
<property name="build.dir" value="build"/>
<target name="init" description="initialization target">
<echo message="=========== Build Adempiere - ${env.ENCODING}"/>
<!-- Create the time stamp -->
<tstamp/>
</target>
<target name="jar" depends="init">
<ant inheritAll="false" dir="tools"/>
<ant inheritAll="false" dir="base"/>
<ant inheritAll="false" dir="extend"/>
<ant inheritAll="false" dir="client"/>
<ant inheritAll="false" dir="JasperReports"/>
<ant inheritAll="false" dir="JasperReportsWebApp"/>
<ant inheritAll="false" dir="serverRoot"/>
<ant inheritAll="false" dir="serverApps"/>
<ant inheritAll="false" dir="webStore"/>
<ant inheritAll="false" dir="webCM"/>
<ant inheritAll="false" dir="sqlj"/>
<ant inheritAll="false" dir="posterita/posterita"/>
<ant inheritAll="false" dir="zkwebui"/>
</target>
<target name="build" depends="jar">
<ant inheritAll="false" dir="install"/>
</target>
<target name="clean">
<ant inheritAll="false" dir="tools" target="clean"/>
<ant inheritAll="false" dir="base" target="clean"/>
<ant inheritAll="false" dir="extend" target="clean"/>
<ant inheritAll="false" dir="JasperReports" target="clean"/>
<ant inheritAll="false" dir="JasperReportsWebApp" target="clean"/>
<ant inheritAll="false" dir="client" target="clean"/>
<ant inheritAll="false" dir="serverRoot" target="clean"/>

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 37
<ant inheritAll="false" dir="serverApps" target="clean"/>
<ant inheritAll="false" dir="webStore" target="clean"/>
<ant inheritAll="false" dir="webCM" target="clean"/>
<ant inheritAll="false" dir="sqlj" target="clean"/>
<ant inheritAll="false" dir="posterita/posterita" target="clean"/>
<ant inheritAll="false" dir="install" target="clean"/>
<ant inheritAll="false" dir="zkwebui" target="clean"/>
</target>

<target name="clean-all" depends="clean">


<delete dir="${env.ADEMPIERE_ROOT}"/>
</target>

<target name="update-adempiere-jar" depends="init">


<ant inheritAll="false" dir="base" target="compile"/>
<ant inheritAll="false" dir="extend" target="compile"/>
<ant inheritAll="false" dir="client"/>
</target>

<target name="update-serverRoot" depends="init">
<ant inheritAll="false" dir="serverRoot"/>
</target>

<!-- ================================================ -->
<!-- Adempiere Local Install -->
<!-- ================================================ -->
<target name="install" depends="" description="Environment dependent">
<echo message="=========== Install Adempiere"/>
<copy todir="${env.ADEMPIERE_INSTALL}" verbose="true">
<fileset dir="install/build" includes="Adempiere_*"/>
</copy>
<!-- Delete Existing stuff, but not utils + data -->
<delete failonerror="false">
<fileset dir="${env.ADEMPIERE_HOME}/lib"/>
<fileset dir="${env.ADEMPIERE_HOME}/jboss"/>
</delete>
<!-- Unzip Install File -->
<unzip src="install/build/Adempiere_${env.ADEMPIERE_VERSION_FILE}.zip"
dest="${env.ADEMPIERE_ROOT}"
overwrite="yes"/>
<!-- Run Setup -->
<!--
<input addproperty="runSetupInput"
message="Run Setup(Y/N) ? "
validargs="Y,y,N,n"/>

<antcall target="runSetup"/>
-->
</target>

<!-- ================================================ -->
<!-- Adempiere Local Update -->
<!-- ================================================ -->
<target name="updateDeploy" depends="" description="Environment dependent">
<echo message="=========== Update Adempiere"/>
<copy todir="${env.ADEMPIERE_INSTALL}">
<fileset dir="install/build" includes="Adempiere_*"/>
</copy>

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 38
<!-- Unzip Install File -->
<unzip src="install/build/Adempiere_${env.ADEMPIERE_VERSION_FILE}.zip"
dest="${env.ADEMPIERE_ROOT}"
overwrite="yes"/>
<!-- Run Setup -->
<antcall target="runUpdateWin"></antcall>
<antcall target="runUpdateNonWin"></antcall>
</target>

<target name="runSetupInit">
<condition property="isWindows">
<os family="windows" />
</condition>
</target>

<target name="runSetupWin" depends="runSetupInit" if="isWindows" >
<exec dir="${env.ADEMPIERE_HOME}" executable="RUN_setup.bat"
spawn="false" resolveexecutable="true">
</exec>
</target>

<target name="runSetupNonWin" depends="runSetupInit" unless="isWindows" >
<chmod dir="${env.ADEMPIERE_HOME}" perm="ugo+rx" includes="RUN_setup.sh"/>
<exec dir="${env.ADEMPIERE_HOME}" executable="RUN_setup.sh"
spawn="false" resolveexecutable="true">
</exec>
</target>

<target name="runSetupCheck">
<condition property="setup.yes">
<or>
<equals arg1="y" arg2="${runSetupInput}"/>
<equals arg1="Y" arg2="${runSetupInput}"/>
</or>
</condition>
</target>

<target name="runSetup" depends="runSetupCheck" if="setup.yes">
<antcall target="runSetupWin"></antcall>
<antcall target="runSetupNonWin"></antcall>
</target>

<target name="runUpdateWin" depends="runSetupInit" if="isWindows" >


<exec dir="${env.ADEMPIERE_HOME}" executable="RUN_update.bat"
spawn="false" resolveexecutable="true">
</exec>
</target>

<target name="runUpdateNonWin" depends="runSetupInit" unless="isWindows" >
<chmod dir="${env.ADEMPIERE_HOME}" perm="ugo+rx" includes="RUN_update.sh"/>
<exec dir="${env.ADEMPIERE_HOME}" executable="RUN_update.sh"
spawn="false" resolveexecutable="true">
</exec>
</target>

<!-- ================================================ -->


<!-- complete -->
<!-- ================================================ -->

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 39
<target name="complete" depends="build, install">
</target>

<!-- ================================================ -->
<!-- update -->
<!-- ================================================ -->
<target name="update" depends="build, updateDeploy">
</target>

<!-- ================================================ -->


<!-- Transfer Install -->
<!-- ================================================ -->
<target name="transfer" depends="complete" description="Transfer to Distribution media">
</target>
</project>

The above build xml is to compile each package of the sourcecode tree and jar them into
a binary structure for deployment. The following build xml is for applying the SQL
scripts that upgrade the database since the last version release. Each SQL will add,
change or delete certain table-field structure in the database so as to work with the latest
revision in the trunk.

Usually each developer or committer as they commit code changes will also commit the
accompanying database changes in the form of those

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 40
Figure 2.6 - Build.xml of migration folder

<project name="migrate-db-postgre" default="run-scripts" basedir=".">


<property file="../../postgresql.properties" />
<path id="lib.path">
<fileset dir="../../../tools/lib">
<include name="**/*.jar" />
</fileset>
</path>
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<fileset dir="../../../tools/lib">
<include name="**/*.jar" />
</fileset>
</classpath>
</taskdef>

<target name="init">
<echo
message="============================================================" />
<echo message=" PostgreSQL database update tool for Adempiere ERP" />
<echo message=" Adempiere Licese is GNU GPL License" />
<echo
message="============================================================" />
<echo message="" file="psql.log" append="false" />
<echo append="false" file="build.log" message="#Build log:${line.separator}${line.separator}" />
</target>

<target name="run-scripts" depends="init">


<echo message="----- Running migration SQL scripts -----" />
<echo file="psql.log" append="true" message="${line.separator}#Run Scripts:${line.separator}$
{line.separator}" />
<foreach param="file.name" target="load">
<path>
<fileset dir=".">
<include name="*.sql" />
</fileset>
</path>
</foreach>
</target>

<target name="load">
<echo message="Loading file ${file.name}" />
<exec dir="${postgresql.home}/bin" executable="${postgresql.home}/bin/psql"
resultproperty="psql.result" output="psql.log" append="true">
<arg line="-h ${postgresql.host}" />
<arg line="-d ${postgresql.database} -q" />
<arg line="-U ${postgresql.user}" />
<arg line='-f "${file.name}"' />
<env key="PGPASSWORD" value="${postgresql.password}" />
</exec>
<echo message="File ${file.name} status ${psql.result}" />
<echo append="true" file="build.log">File ${file.name} status ${psql.result}</echo>
<echo append="true" file="build.log" message="${line.separator}" />
</target>
</project>

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 41
2.7 SourceForge.net Project Management
One really big shoulder that work tirelessly in the background and over a global scale is
non other than the free utilities and facilities provided by SourceForge.net (www.sf.net).
This commercially owned web based repository offers free access to hosting and tools
for developers of free and open source software. It competes with other providers such
as RubyForge, Tigris.org, BountySource, BerliOS, JavaForge and GNU Savannah[4].

Project developers have access to centralised storage and tools for managing projects. Its
great benefit to FOSS projects is by providing revision control systems such as CVS,
SVN, Git and Mercurial. Major features (amongst others) include project wikis, metrics
and analysis, access to a MySQL database, and unique sub-domain URLs (such as
http://project-name.sourceforge.net).

The vast number of users at SourceForge.net (over 2,000,000 as of 2009) exposes


prominent projects to a variety of developers, and can create a positive feedback loop.
As a project's activity rises, SourceForge.net's internal ranking system makes it more
visible to other developers who may join and contribute to it. Given that many open
source projects fail due to lack of developer support, exposure to such a large
community of developers can continually breathe new life into a project.

SourceForge repository servers being mirrored in many countries particularly in the


developed nations, allowed global communities to have same level playing field in
collaborating around the clock. A completely multi-national community such as ours
has turned into a borderless village, thanks to SourceForge. We used it for almost all the
essential activity in managing the development of the software - from reviewing and
committing code, managing committers’ rights that allows or disallows members from
committing to trunk, uploading file releases and documentation, tracking project
statistics, right up to giving overall high visibility to the whole project with non-stop
forum exchanges.

I sometimes wondered how life would be without SourceForge. Well, we might use one
of its many competitors now, but in those early 2000s, we might not have known
Compiere that easily and came together this nicely into its community fork. Being there
as the largest and most active FOSS project repository in the world has made it a critical
mass and mecca for all travellers and traders in FOSS.

Among the many tools we used on SourceForge, perhaps the most crucial in ensuring
the global visibility of the software is the Tracker for bug fixes and feature requests as
well as the SVN commiting from Eclipse. SVN or SubVersion is another open source
tool in its own right. These two giants allow us to work in concert seamlessly. Eclipse
has an SVN plugin that can be set pointing to the repositoryin SourceForge. Developers

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 42
who are allowed commit rights will use their favourite IDE such as Eclipse and made
commits of new codes to the repository’s trunk right from the IDE without leaving it.
The commits are automatically sent to SVN and the committer’s comments are posted
as a message which is sent to the SVNlog mailling list which all the developers and
members of the public who suscribed to it shall receive.

This allows most of us to wait by our mailing boxes to examine each mail from the
trackers. Some senior committers can quickly revert any ill-done code without spending
too much time searching for them through the repository. What they do usually is to
update the changes back into their IDE project. A quick compile and test can be done. If
the logic is not to what they expected, they can trace the last code commit concerned to
the tracker revision number and comment back there and another message is sent back
to the same tracker. The messages are automatically formated as the one below here.

Figure 2.5 - Message automatically sent after a commit via Eclipse

Notice that in this commit by Victor Perez of Mexico, he put a tribute in his comment to
another committer, Low Heng Sin of Malaysia. The minus sign in the message is saying
Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering
P a g e 43
that the line after the sign is being deleted and replaced with the line after the plus sign.
Those two signs and the deleted line shown are automatically done for spot-on
reference by the SVN tool in SourceForge. Without them many, many hours resulting in
wasteful effort and unproductive work will have occured and the project will be very
slow and cumbersome to manage.

In this manner, all developers concerned who has their Eclipse ready pointing to the
SourceForge repository will be on par with everyone else. The most up-to-date
committer’s version is just a click away. Everyone truly seem to be in the same room.
SourceForge, Eclipse and the web has made free software engineering into a
phenomenal experience where the smartest people no matter where they are can truly
be working on a single project, seemingly without a project manager or wading through
tiring close door meetings. The morale and spirit is highest when you are working with
such a gifted group of people that comes from many cultures and backgrounds.

The tracker messages will display again all the previous comments to it since inception.
The long one below here is a good recent example. It is shown here in 2 parts.

Figure 2.6(1) - Feature Request Discussion Thread

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 44
Figure 2.6(2) - Feature Request Discussion Thread

From this email message you can see the interactive ‘conversation’ from others about
the same matter. There is Paul Bowden from ADAXA, a prominent Compiere/
ADempiere expert implementation consultant company based in Melbourne, Australia,
followed by Ian Chris (Dellph), a DIY programmer from Mindanao, The Philippines.
Finally Carlos Ruiz from Colombia who originated this Feature Request could respond
back and a technical conversation takes shape. Such a system of communication
resolved a few birds with a single stone. Firstly there is documentation with a running
unique reference number which is the holy battle cry of all project owners. Then there is

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 45
traceability of what happened to that tracker for anyone who followed later to have all
related progress information at their fingertips - either in their mailbox or from the
repository archives. And all this is always online, 24 X 7, in hundreds of mirrors
worldwide! There are tens of threads been conversed hundreds of times each day in the
trackers and forums, many with their own little virtual committees exclusive to their
own domain area of expertise.

No closed software team can beat this. Not when all this is absolutely free and done on
a voluntary basis. I as the pathetic temporal leader have no say, have no control and
have no idea in such discussions. They are all technically more superior than me. Yet
there is no mutiny. Not yet, I hope!

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 46
2.8 Usability and Stability
The main issue or challenge facing the ADempiere project is to ensure that the
application is stable and usable by commercial parties. In other words it has to be of
production quality. Now, this is a tricky matter as the software environment is always in
a state of flux. Bugs are found and fixed on a daily basis. Sometimes all round the clock
as different locations around the world wake up to examine what is done by the other
side that has retired to bed.

Before a production quality version is released, the trunk where the sourcecode is kept
is frozen so that new features are not sent to it which can destabilise the trunk. But we
cannot stop innovation that is equally important in an open source project. Those new
features are allowed to be in their own branch or in a development trunk.

After a period of stabilising where high priority bugs are sieved through and resolved
or worked around them, a peer agreement is made to create a binary release by
compiling the sourcecode in the trunk. The proper process of this is of great importance
as most users are real-life users with real-life businesses to run on. They are highly
sensitive if the software is unstable or unusable. Even though according to the GPL
license, the software is to be used on an ‘as is where is’ basis, its larger meaning is for it
to be really used for business purpose. With this understanding, it puts a dualism onto
the whole project. On one stage, the project is a hobbyist dream, to hack the canvas of
software with strokes of creativity, but on the other hand, is to ensure the paint stays on
the canvas for the audience to make sense of it. This remarkable interplay of opposites
has led to some expected differences of motivations of which ADempiere also cannot
escape from.

It is not uncommon to find code commits reverted the very next instance, with heated
exchanges of opinions. It is like the ‘egg and chicken’ analogy. If you do not commit a
script, how then can we let the world test it? If we are to test it first, we will delay any
release! The ‘Release Early, Release Often’ mantra attributed to Linus Torvalds is not
precise as to what exactly is ‘early’ and what exactly is ‘often’!

There were many arguments or flames in cyber speak, between strong technical opinion
and strong end-user opinion. Fortunately the majority agrees that the project’s end
product is still an ERP software that must work well and satisfy end-users and not
technical developers.

Thus the miracle that the project not only survives, but is able to make release after
release that wins more and more followers, is either an act of unconscious compromise,
or chaotic harmony.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 47
2.9 ZK Ajax from Low Heng Sin
The latest craze to hit the world just a couple of years back was Ajax where a smart way
of refactoring a combination of old technologies such as DHTML and XML with nice
JSPs can make the rather strait-jacketed web browser behaves more customised and
responsive as never before. Widgets are abound and panels can be dragged around
effortlessly.

When ADempiere first forked from Compiere, there was already another commercial
open source fork, OpenBravo that resolved the boring and alpha level of its basic
HTML interface, which was built on old servlets with JSPs technology. It was not even
finished and was not really usable for production instances. So for us in ADempiere we
were basically out on our own as we struggle with the massive challenge of first
consolidating our existence that was entirely virtual with no physical central command
centre and no budget to work on. We had a long list of dreams including making
database independence from Oracle and resolving many bugs that riddled the
application as well as moving it along a roadmap that includes Libero Manufacturing
and Business Intelligence integration.

What was and still is amazing is the sudden appearance of Low Heng Sin who happens
to stay 20 km from where I was or a 15 min drive away. I invited him into the
developer’s list in those early days thinking that he was just a young normal newbie
developer that needs some of my encouraging words. Now my assumption is totally
wrong as he turned out to be the most amazing contributor that can rival the speed of
Carlos Ruiz himself. Heng Sin contributed not only better code all round, but helped
bring to production status many items on our long list with vast and ingeniously
crafted improvements to PostgreSQL porting, Java Swing, core modules and this Ajax
interface to replace the old HTML one. Now we can say that the Ajax UI is very
production ready and may have truly save our day as it certainly can rival OpenBravo’s
similar use of Ajax technology and Compiere’s usage of GWT, another flavour of Ajax.
(We even have a GWT implementation lurking in the background and that is been
developed by e-Evolution of Mexico, another great contributing group under Victor
Perez.)

It is also noteworthy that actually ZK Ajax introduction into ADempiere was done by a
small company in Mauritius, called Tamak, but changed its name to POSterita after
meeting me in end 2006. POSterita however abandoned its contributions that include
Webstore and an advanced POS system due to differences in branding strategy with the
rest of us. The ZK Ajax UI contribution from POSterita that time was very rudiment but
a good start and entry point for Heng Sin to pick up and advance on solidly and quite
single-handedly. We still maintain the credit of saying that POSterita is the contributor

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 48
of ZK Ajax but we have to add the qualifying statement that Low Heng Sin completed
it, without mentioning the vast monopoly of codes Heng Sin has put into it. Well, not
there but at least I am mentioning it more formally here now in this book. Heng Sin
after some rare meetings with him has impressed me as someone rather private and
humble, yet firm and correct on technical issues. He shun political debates or
confrontational flames within our forums and often choose small words. They are often
short and just limited to technicalities, but of very deep importance to the direction of
significant parts of the software development. He even turned down an all-expenses
paid trip to our 2nd Berlin Conference recently on 21st June, 2009 citing flimsy reasons
such as Berlin as too far from his home here in Malaysia and he does not see himself
contributing in a physical
roundtable discussion. When
he turned down Kai
Schaeffer’s invitation on behalf
of the ADempiere Deutschland
e.V to participate in the
conference, I waited until Kai
was here in Kuala Lumpur,
under an invititation from
MDec, the organisation for our
MSC (Multi-media Super
Corridor initiative) to attend
Malaysia’s first ever Open
Source Conference on 1st June,
2009. Even at the private
dinner together with Bayu
Cahaya, another contributor
from Indonesia, we could not
persuade Heng Sin to come to
Berlin. Not even the possibility
that all the other greats such as
Carlos Ruiz, Victor Perez,
Trifon Trifonov, Teo Sarca and
Karsten Thiemann will be
there, and everyone wants to
meet him.
Figure 2.7 Top photo, left to right - Kai,
Heng Sin and Bayu. Bottom - our dinner
early June, 2009 to persuade Heng Sin to
come to Berlin.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 49
Wel, so much for the legend that rise even higher on the charts for being so elusive and
obscure. Now let us see what he has done by following some steps below. First we
launch the application server by executing the Server2 shell script (for Unix based
platform) or Server2.bat (for Windows based platform).

Figure 2.8 Launching the app server

After some minutes we can pick out the IP prompted within. Noted below it is
10.37.129.2 with port number 8088.

Figure 2.9 Getting the IP and port number

Then we call up our favourite browser and put in the IP and port into the location. We
will then have the Adempiere HTML admin page appearing, where we then click on the
Adempiere ZK webUI link. When it comes up, login as SuperUser and key in the
password as System. You shall see the amazing ZK Ajax UI in action. Click around the
widgets and icons and even drag around some of them to see how fantastic it is.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 50
Figure 2.10 ADempiere’s ZK Ajax User Interface as completed by Heng Sin

It is important to note that Low Heng Sin, like most of us, does not survive without
income. So what he has contributed is what he was paid for and in this case, the Ajax
works are being sponsored by Idalica of USA. This fits very nicely with the 3-line
mantra I promoted in my www.red1.org website and the www.adempiere.org site:

1. Information is Free - You have to Know

2. People are Not - You have to Pay

3. Contributors are Pricelesss - You have to Be.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 51
2.10 Private Forking from Anyone Else
I have to touch on the silly side that may happen after all the good stuff talked about
above. As the sourcecode are free and any party may fork the project, there will be
attempts to fork it privately and not contribute back. Or at least contribute back but
under commercial self-ownership terms that alienate the community. Not letting the
main project receive any of your contribution unconditionally is fine. What I like to
point out is that you will be back at square one. Remember the software crisis
explanation from page one. It will return to haunt you. You will not be able to maintain
your private project, or you will begin wasting precious money hiring people to do that
for you who can then leave and fork yours too. The risks are aplenty. When originally
there were few or as I often argue hardly commercial any risks with FOSS, if you
manage it wisely along this new paradigm.

There will be a need for you to package and rebrand your works and that cost more
money (see figure on next page). Then there is marketing to promote at least by word of
mouth. More money. What about time spent reselling? Preselling? Follow up meetings.
More money. In the end you have to ask yourself is it worth it wasting money as a
private enterprise. Not only that. You will not be the only smart ass in the room. There
are countless others already doing what you are thinking of doing. They are all
competing in the little alleys for the main street attention. That they won’t get because
the main project is in the way.

If we in the ADempiere project think about closing up or selling off to a major player,
we will lose value and face almost overnight. Just like what happened to Compiere or
OpenBravo. The millions given to it has to be repaid nevertheless. But the value they
hope to exact from the market is already diluted. Many already know about the other
parent or fork projects. There is no barrier to keep them ignorant. They can just google
and find out the truth.

Linux is free and cannot be stolen. It can be forked and repackaged as Tomix. But who
will pay for it? How to hide the look and feel more convincingly? How to avoid expert
eyes from figuring out what actually is under the fresh coat of paint?

Going private will out you back at the start of the food chain because providing post
installations of mainstream adopted ERP systems can be a major source of income. This
is in accordance to recent analysis conducted which state that many organizations do
not realise that the total cost of ownership of an ERP system is composed largely of
ongoing support[5]. Something that is real but not yet realised is more blue an ocean to
swim in than copycat in a red one.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 52
Figure 2.10 More Cost From Private Ownership
Source: Northwest Regional Educational Laboratory, Portland, Oregon. www.netc.org & www.nwrel.org

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 53
Quiz
1. List down all important FOSS projects that ADempiere benefits greatly from.

2. What was Jorg Janke’s contribution to ADempiere?

3. Is private forking commercially viable? Why?

Glossary

Term Description

Social The art of behaving in socially acceptable manner to the


Engineering community so that pragmatic progress can be made.

Trunk The main location where sourcecode is kept and updated to

Branch Separately maintained part of the trunk where development or


testing is done for easier management.

Business The ability to analyse data and present in high level but statistical
Intelligence formats usually done with software tools.

SourceForge.net The most popular and largest repository for Open Source projects
to house and operate from.

IDE Integrated Development Environment such as from Eclipse and


Netbeans

FOSS Free and Open Source Software, with specific licensing i.e. GPL

Forking To continue or take the work of a project and do it in a different


direction for business and political reasons.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 54
Summary
4. Open Source allow more unabated growth from open participation by developers.
users and implementors.

5. ADempiere stood on many giants’ shoulders besides Compiere, such as Eclipse, ZK


Ajax and PostgreSQL for more independence from vendor specific limitations.

6. Tools such as JasperReports allow n-tier freedom to the ERP Application in that it can
now access directly the database for ad-hoc reporting.

7. SourceForge.net providse a lot of free facilities such as sourcecode storage and


tracking, constant and global availability through a worldwide network of mirror
servers.

8. Private forking of an open project is not necessarily viable from a business sense
unless it is providing something that the open project does not.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 55
References
1. http://www.cyber.com.au/users/conz/shoulders.html

2. http://blogs.zdnet.com/Burnette/?p=387

3. http://www.adempiere.com/images/9/96/SpagoBI_&_ADempiere_en_.pdf

4. http://en.wikipedia.org/wiki/SourceForge

5. http://www.computereconomics.com (search for ‘ERP Support Staffing Ratios’)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 56
Chapter 3 - Application Strategy

Learning Objectives
By the end of this chapter, the student shall be able to:

1. Compare the strategic benefits of ADempiere;

2. Describe the strategies of deploying ERP solutions today;

3. Provide examples of technologies used in software development;

4. Put forward the next wave in business applications and tools from FOSS.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 57
Introduction
Formerly, most users wishing to adopt a new software particularly ES will ask
themselves the following question: Should I buy or should I build? Today they can ask
a more distinctive question: Is there a free ready-to-go one out there?

Since the appearance of Compiere in 2000, the marketplace of shopping for Enterprise
Software began to change. Now users have a choice of going free. After Compiere’s
creators milked the free-riding branding to amass a small fortune, it turned more
commercial and leave it to others to inherit its GPL discarded codebase.

ADempiere inherited an application strategic structure from Compiere that is highly


versatile and elegant. It allows rapid application development (RAD) quite on the fly
without coding work. RAD, fast-prototyping, Extreme Programming besides Open
Source are terms commonly heard today in the vulnerable age of software crisis.

Studying how the Compiere application strategy works can be a reference point for
other business applications. Compiere is a first grade ERP system[1], nothing miniscule
like your daily General Ledger book keeping software. To work or change it requires
not only holistic profound understanding but also pills of patience through a sharp
learning curve. The bright side is that if you come out the other side like I did, you can
be called a guru, like I am.

There are many new application makers out there mushrooming as we speak.
Differentiator is that they have to have enough functional maturity that Compiere and
ADempiere now has. The later has gone through great communal baptism the last 3
years, with many lines of codes and feature snippets scrutinised - understood, modified,
improved, refactored or thrown out. Functionality is king with end-users. All
applications have to remember that.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 58
3.1 Software Building Strategy
In the market today, and when we talk about the market, it greatly involves free stuff as
you can easily find from open source, where we can find an exploding supply of ideas
on how to develop software. Just do a Google search will turn up endless list of choices.
Incidently the only way to cut through the marketing or adveritisng dollars is to ask the
following:
1. Do they have an active, volunteer community?
2. If they are new, are there reviews by independent community opinion, mostly in
blogs, wikipedia and other community forums?
That’s it.

Searching via any search engine can assist. It is the lots of reading that has to be done.
When doing such a search for “Software Development Strategy” it returns 54 million
hits. In them we will come across the following buzz words:
1. Agile
2. Team based
3. Interoperatibility
4. Documentation Generating
5. Standards Compliance
6. Open Standards
7. Client Server versus Distributed Architecture
8. Supplier Performance & Risk
9. SOA - service oriented architeture
10. Why build? Just uses SaaS - in the Cloud!
11. Or use a Rapid Software Prototyping Tool

Many of these buzz words can be confusing and especially so that the software industry
is very strictly vendor driven. All vendors have their own say on all things. Oracle has
its own version of standards and software strategy. So does Microsoft. Nevertheless we
can find them using the same buzz words. Just watch out for collective stupidity. An
example is SaaS (Software as a Service) which is a repackaging of the failed ASP model
(Application Service Provider). The idea is to tell the customer not to buy software and
set it up inhouse but rent it and have it setup at a data centre. For ERP users, this is
tricky because, like the very first statement I made in this module about how long it

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 59
take to setup an ERP system, it involves alot of business processes intertwining with
people processes within the user organisation. Users want the ERP to work their way,
not the vendor or provider’s way. To go Cloud computing is a nice buzz word adoption,
but sadly it is just a latest fad, fueled by dinosaurs competing on the range.

Thus many users are left to pick and choose from the market their own interpretation of
the best buy or build from scratch option. Now, you should strike out the later option
because nobody builds from scratch. You may be surprised but I have come across
many who do! Either they are dreaming of been the next Bill Gates or they felt no one
out there understand or fit their requirements. This is where rapid prototypers may
come in. Do a search for it and again a popular vendor such as Microsoft’s name comes
up. Using Microsoft for instance will lock in the user to a certain vendor’s stack of
software which can be costly and unwieldy to break off from in case of a change of
heart.

There are many building buzz words to speak of and the following often comes to
mind:

1. Java Frameworks like Struts, Spring and OfBiz

2. Easy programming languages such as Python, Ruby and Groovy

As you can see, these are still tools and not the finished buildings or machines. Here I
am giving a strong hint that there is no holy grail of finished friendly dragon that can
take you up into the sky. I have came across some such as JBoss BPM, Groovy
generators, but they are just nice bodyframes with missing parts inside. (There is OfBiz
as an exception that we shall touch on later). There is no business content of business
processes. You will have to build it from scratch. From here we can examine the
Compiere family particularly ADempiere’s due to their inherent body parts and ready
made cushioning. Among their available inbuilt business content features are:

1. Accounting engine to post debits and credits generated in each document transaction;

2. Document Type definition of Sales and Purchases (Orders), Vendor and Customer
Documents (Invoice, Shipments and Payment);

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 60
3. Workflow engine to process documents’ states such as pending, approved,
clompleted;

4. Multiple currency exchange and resolution of its variance in the accounting;

5. General Ledger Journal management and direct accounts posting;

6. Protected audit trail where values cannot be easily deleted;

7. Role access levels for different departmental users;

8. Multi-user environement and even internet-based performance;

9. Product management and inventory locators populations;

10. Self service e-commerce engine;

11. Web based trouble ticket request engine.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 61
3.2 What About OfBiz?
OfBiz is said to offer considerable ERP functionalities such as Order taking and E-
commerce but its presentation is very technical and require a more steeper learning
curve. To give due credit to OfBiz[2], it is another application suite really worthwhile as
it is created with more recent technology than Compiere’s and does not have certain
acrhitectural problems such as scalability, true DB independence, n-tiered and
modularizability.
However in doing comparitive analysis there are some weaknesses in OfBiz such as its
accounting engine[3]. However OpenTaps is said to be a more accounting bent fork on
OfBiz and may warrant a closer look. In deciding between Compiere types and OfBiz
types, one has to think between stronger functionals versus stronger architecture. Both
are in a state of dynamic development. ADempiere is trying to get more architecturally
modular (check back in a year perhaps) and OfBiz will hope to get more powerful
functionals integrated into its body. But accounting is a deep subject not easily
discerned by technical people. This is what differentiates Compiere ‘s group from the
pack. Its creator Jorg Janke has strong accounting background, reputed to have a
qualification in financials accounting. A take on Compiere’s Jorg Janke against OfBiz’s
creator, David Jones is published in a research paper by TEC[4].
The idea one gets after reading the last research interviews with both creators, is that
Compiere is created with accounting in mind, whereas OfBiz is created with the
applicaiton framework in mind. Thus OfBiz’s weakness is that accounting which is
crucial is not owned by the project but open to 3rd party participants. Compiere has
accounting done from the ground up under direct ownership in the project. Accounting
processes is a very tedious and encompassing journey. In the ERP Accounting module
later we shall go through a whole accounting process in detail. Having said that, OfBiz
may juat await the right saviour in the form of an expert software accounting firm to
move it into the top notch. But there will be pressures. One is the urge to close source.
Next is a question of strategy. Wouldn’t it be more cost-effective for that saviour to
migrate ADempiere to OfBiz than to upgrade OfBiz with ADempiere?

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 62
Figure 3.1 A new application can be a quick vertical in ERP

3.3 Software Building Model


Many have gone looking for the holy grail of software development tools and often
came back empty handed. For us here (do not take our word for it) ADempiere is the
'Pretty Good' framework to use for any serious financials related enterprise
development. It requires serious hands-on learning curve, say 3 to 6 months by a
passionate team. Here we have a sample case of a prospective application 'EIDA' or
Economic Intelligence Data Analysis already deployed on top of a national database of
agricultural produce.

Some of the wishlist of such a new software model will go along the following lines;

* It likes to go backwards into some suitable ERP functionality.


* It wants to do order processing and document flow.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 63
* It wants to keep track of product and database expansion
* It wants to integrate with many things along the highway.
* It wants it fast, cheap and good.

The first thing a new application has to do is to trade-off with the ADempiere project.
* It has to offer something in return
* It has to exploit the community open source paradigm
* It has to be useful to the horizontal ERP and other verticals
* It has to be componentised and portable
* It has to earn potential income to the contributor due to its branded domain expertise

The benefits to the contributor is:


* Reduced development team. It can contract the best developers already present in the
community.
* Reduced development time. It can rest on a proven and stable application framework
that already has inherent working features.
* Reduced reinvention of the wheel. It can make use of any stated ERP functions.
* The business direction for the contributor is:
* To facilitate global presence of its vertical. It may offer training and consultation as to
the subject expertise behind the application. In this case it is economic intelligence.
* To position its name and services within the community resources. Its name can
appear on the site and application credits page.
* To work with community representatives worldwide. It need not overstretch but
make use of present network as its reseller front.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 64
Dual Mode Strategy
* Going community open source allows the contributing company to enjoy tremendous
marketing and branding.
* Less reliance also on bloated marketing budget. Non-core activity elimination can
happen.
* Open information spells out its services model clearer to the market. Less demand for
presales effort.
* Small-time users will take DIY Mode and not pay for high-worth services fees.
* High level users get the ground swell and engage disruptively upstream with Flagship
Mode providers.
* Large vendors threatened and react either matching the FOSS move and thus dilutes
itself.
* Or differentiates further thus pushing up the water level.
* Either way the FOSS player travels light and moves above the water level and awaits
market understanding.

Figure 3.2 Advantage of building on community FOSS ERP project

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 65
Contributor Makeup

Figure 3.3 - EIDA is a sample idea that can be contributed. If not, someone else will

The contributing company should not have over-reliance on own local IT and developer
resource. Java or ERP resource is expensive and even more expensive to keep. Just have
a skeletal 3 man support team per base is sufficient. Rely more on short term and well
paid expatriate team already available in the community. Hire our best brains and
hands to ensure a quick kickoff and exit strategy. Keep lean and beam. Not mean. Go
up your own value chain. Be better in what you are good at and nothing else. High
worth deals only seek for high worth consultancy and services. Seek a niche and not be
everything to everyone. You will soon dry up and no one pays a dime more. There are
many more cups better than yours.
Focus to enjoy more
You won't like a big headache from big office and staff. No one likes you having big
headaches all the time. When you are having fun, you won't mind failing. It is already
paid for.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 66
Business Horizon
* ERP is getting hot. Most SME to large enterprises have software that need changing
between 5 to 10 years. Most software half-life ends in 8 years.
* Open Source is even hotter. If yours is not free, someone else is. In fact, almost
everyone else is. Even Microsoft gets it.
* Been number one is hottest. ADempiere is not only number one, but will explode
further every season due to unabated growth.
* Pressure of ubiquitous and disruptive integration tolls on limited expert resource. No
one can remain closed and even compete.
* Many ERP projects fail. More pressure for quick and easy wins.
* ERPs need to be everything to everyone. Every business has a specific issue that big
shops cannot address. No single company can do more. But a community can. A
borderless timeless one.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 67
3.4 Rapid Application Framework
Motivation

Today's needs are on the fast-track. Users want an ERP within 6 months instead of 18
months. ERP apps have bloated to become everything to everybody and one size fits
all. Quality large scale implementations can no longer be done by a single expert and
requires open sharing among all parties. Speciliasation by differentiated contributors
lower total cost of ownership for paying users.

ADempiere As An Application Framework

Figure 3.4 - The DataModel is integrated to the Application Dictionary

Since ADempiere's Application Dictionary resolves the need to touch sourcecode or


base software to a minimum, and allow changes to be made rapidly and conveniently to

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 68
not only the look and feel of the Data Model but also the Business Model, we can call it
an Application Framework.

An Application Framework basically helps you to develop an application without


starting from scratch. ADempiere already has the look and feel and many accessories
resolved to work stably and marvelously. Such features and accessories need not be
coded further in a fresh software design. A new software to be created can just
introduce its DataModel as Tables and Columns arranged within Windows and
attached to Menu Trees. Each User login will be controlled by its allowed Role or Roles
to access or not to access certain Menu of Windows or Processes or Reports.

Application Modelling

Figure 3.5 - Any vertical application can be incorporated and reuse standard utilities

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 69
ADempiere acts as a horizontal application where other or new vertical applications can
reuse or sit on it. Before a new application is introduced, it need to be designed and
modelled accordingly that fits onto the ADempiere Framework. To design a new
application on top of ADempiere is perhaps the hardest or biggest portion of the cost of
an application development.

• Any application design is hard. The bigger it is the harder it is. The more modules to
integrate, the challenge increases exponentially.

• But spend enough time planning it (50%), and enough time designing it (90%), the
coding part is only 10%.

• The resulting work to code or migrate the system to is simple.


There are various migration tools to do the final integration of legacy application data
or model into ADempiere. Among them are the:

• Import Loaders (incumbent model)

• ADCK (XML2AD enhanced model by Trifon T.)

• 2Pack (XML2AD enhanced model by Robert Klein - standard for migrating own apps)

• Log Migration Scripts (standard for new apps)


• OSGI Module deployment (under construction)
The importance at the systems design stage is to study the inherent ADempiere model
and framework well enough to reuse them to the maximum and to avoid work
redundancy and later complications.

A succesfully introduced or migrated vertical application will enjoy not only the
incumbent multiple rich interfaces and application engine, but also a quantum leap into
the open source services market.

Intending application developers must realign their Software Business Model to an


entirely new one.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 70
Data Modeling
NOTE that where the word 'must' is used would mean that it is mandatory and non-
negotiable for successful implementation.

The word 'should' would mean that it is optional but encouraged for maintainability
and scalability of the system.

• SQL scripts for each data model can be executed first in the Database. Then the AD's
Table and Column can bring in those created tables into the Application Dictionary.

• Each table must have the compulsory fields for model persistence and management
within the ADempiere Framework:

• AD_Client_ID - signifies the highest level and distinct identity that owns all the
organisational activity.

• AD_Org_ID - signifies sub-levels below and within the Client.

• Created - signifies the time-stamp each record in this table at the time of its
creation

• CreatedBy - signifies the User_ID that creates the record

• Updated - signifies the time-stamp each record is last updated


• UpdatedBy - signifies the User_ID that last updated the record

• IsActive - signifies whether the record is active or otherwise.


Each table name must have its primary key as its respective table name plus underscore
ID. For example a new table 'Cigars' will have its PK as 'Cigars_ID'. Any erroneous
naming convention that deviates from this will result in a failed model during
execution.

Each table should have a 'value' field for search key purposes. In short 'value' is another
reserved name in ADempiere's table modeling.

Entity Relationships between tables can be introduced by having fields that possess the
table ID convention. For example another table 'Cigar Smokers' will have 'Cigar_ID' and
this means that it is a Foreign Key to the 'Cigar' table. This is a loosely stated
relationship.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 71
• The presentation of such an entity relationship is within the Window, Tab & Field
setup where a sub-tab will have its its parent key linkage specified. This will tightly
state the relationship but only during Window displays.

• Such apparent master-detail relationship through this PK-FK statement is enforced


during data entry where each detail line possess the parent's ID or primary key.

• Of course you can constraint further within the database constraint setting to say that
if the parent cannot be deleted while having a child still in existence.

• Master Detail table naming should be that the Detail table has suffix 'Line' added to its
name taken from the Master table. For example a 'Cigar' table can be a master table
with a detail table as 'CigarLine'.

Report Modeling

The Reporting Engine in ADempiere (fully inherited from Compiere) is truly on the fly
and hot configurable.

In any window table with records you can click on the Report icon.

• Note the pop up report viewer with your selected single record.
• Click on the Search icon in that viewer.

• Just OK it to select all.

• Note that all records are produced.

• You can thus try to do an Advanced Search to get any report cube you want.

• You advanced preference can be saved for later use.


• Refer to the sample on E-ticketing below about Reporting_On_The_Fly.

• You can reformat the fields and its arrangement easily via the PrintFormat

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 72
Report ToolsBox

Figure 3.6 - PrintFormat engine assist in configuring reports easily

1. In the same pop up window, select the ToolsBox to zoom into the PrintFormat
window

2. Click on the Display Order tab

3. Select those fields you do not want to appear. You can move them around in your
prefered order.

4. Click on the back arrow key to remove them for this report
5. You can then save your new report for later use.

6. Click on the Field Format tab

You can put in further functions such as getting the total or running sum of a field with
amount or countable value.

• When you exit and refresh the report is changed

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 73
• Again all changes are automatically saved in your new report definition.
• And all your customised configurations are transferable either via Log Migration
scripts (prefered) or 2Pack package management.

Advanced Search

There is already an on-the-fly Advanced Search engine to filter any results whether it is
in the display window or the reporting format.

• The boolean rules allow for any set of information imaginable.

• This saves alot of need to create any further engine or tools to produce the right range
of reports.

Figure 3.7 -Advanced search filter can be saved and recalled

1. In the Report Viewer, click on the Search icon

2. Select the items and boolean rules to values needed.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 74
3. Save it with a nice name to recall whenever you want the same advanced search

Process Modeling
Figure 3.8 -A Model goes through various Controller Process that automate work

At the Tab Level

• The AD Framework allows any Field in Table & Column model to have a Callout

• The Callout will do something when OnChange occurs within the field

• Action can be from reading and calculating a new value for any field in the Tab

• Calculation can be accessing any table or changing its value within the Database

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 75
• Callouts can be in Java code compiled into source or in metadata form without
touching the source

• Metadata Callout allows JSR223 scripting options such as from Python, Beanshell,
Groovy and perhaps Ruby as well as Java.

At The Document Level

There is a button field that can spawn a process written in SQL or Java Code

The process can determine an elaborate process:

• Accounts Posting

• Workflow Management

• Records Change
At the end of the process, the button may change its state and the Tab record state is
changed.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 76
3.5 E-Ticketing Example
In this example we demonstrate how the ADempiere framework is suited for rapid
prototyping as well as application development in a sound and scalable manner once
the POC is accepted. The Proof of Concept below will use the following 2 tables for the
simple test.

You run these scripts in the PostgreSQL's SQL editor.

This table is for route trips or schedule of trips available. It stores the origin
(et_departure) to destinations (et_arrival) mappings.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 77
This table is for passenger bookings to check up available trips from the earlier table.

After these tables are created in the database, you can bring them into the Application
Dictionary through the Table and Column window.

Proof of Concept
We could quickly prototype a POC by building 2 tables :-

• one for Vehicle Schedule containing Bus Registration Numbers for each trip;

• and one for Trip Booking to call-up the Vehicle Schedule and return the right Bus
Registration No.

The Table Reference and Dynamic Validation are used to allow a trip planner pull down
list that shows only available trips.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 78
Screen-shots below illustrate the Ajax interface outcome. The Java Client outcome is
same.

Suggested Implementation

• To incorporate schedule confirmation and seating selection as 2 extra tabs under the
Sales Order Window.

• As the 3rd tab's schedule is confirmed, the 4th tab shall display the available seating to
choose from.

• As the seat number is/are chosen, all built information is put as Description in the
OrderLine tab.

• The relevant ticket product with correct pricing is extracted from PriceList Version
table.

• The number of seats is translated to the OrderLine Quantity.

• Alternatively all this extra work can be put into one single 3rd Tab.

Figure 3.9 Image above showing the ‘bus schedule’ information.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 79
Figure 3.10 Booking window to call up available schedules

Pull down lists validated against Bus Schedule above. A Java Callout returns the value
of the Bus RegNo and writes it to the Description field, as well as the Departure and
Arrival venues. Refer to next lesson on Reference Table with Dynamic Validation for
details to achieve this effect.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 80
3.6 The Callout
Here a sample callout org.compiere.model.CalloutBooking.getAvailable is placed in the
Table and Column window, Column Tab.Field = ET_TripEnd.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 81
3.7 Reporting On The Fly

Figure 3.11 Reporting on the fly without a single line of coding needed!

* In the Booking window click on the Report icon.

* In the pop-up report viewer, click on the Search icon.

* Click OK to select all records.

From this E-Ticketing example we can see how the FOSS ERP base we are using can
achieve alot without worrying about the next steps, troubleshooting, and integration.
We can continue focusing on the business model and operational processes more clearly
and build the new modules more surer and faster.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 82
3.8 Reusing Patterns
By now, you probably noticed that there is a certain occurence in what we are doing
when we are handling the application and making it do things better. You can see this
from the way we create the prototype above. There is the data model and the Callout.
Once we look into the codes of many parts of the source, we shall find what we can
regard as ‘patterns’. They are distinctively recognisable after some familiarity going
through them.

Patterns are important because:

1. They are recognisable as larger building blocks;

2. They are repeatedly used and therefore sound in design;

3. They are following a proper design that many developers can recognise;
4. They are reusable;

5. They safe time.

The last points form the highest motivation on why patterns are so important and need
to be stated here as part of the understanding in application building strategy. Later in
the module we will come across lots of of it. For now we can ponder why they are so
important.

Without patterns, the code no matter how much it uses Java, will be wasting it. Java is
meant to build reusable code. Being object-oriented, we can code objects upon objects.
For example we can have a DocumentType object such as Order.java, Invoice.java and
Payment.java. Each object are made up of smaller objects such as get fields, save fields,
or return transactions of a header document. Such functions are again similar across
documents and therefore can reuse similar patterns of code themselves.

Java also allow inheritance where less code is written to say the same thing. You can just
have one calling line to refer to a block code object to carry out a function in a logical
business sense. Example is Invoice.save(). More of this in later chapter on survival Java.
For now suffice to understand that with Java, building pattern of objects and reusing
them is possible and is heavily used in ADempiere. In fact, Java already has ready-made

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 83
common patterns called Blueprints[5]. Remember that this is at the coding level, but
they are getting at the same concept which is reusable patterns.

This concept is borrowed at a higher level and the most famous pattern often refered to
before is the Application Dictionary or AD for short. The AD is what takes our Table
creation scripts above and generate in the application a brand new window with all the
bells and whistles without a single line of extra hard coding. It uses the approach of
dynamic or active code, where the type of window generated is determined at the data
level and not code level. Such data as taught in earlier modules are refered to as meta-
data, or higher data or data about data. What it means essentially is that it is not static.
It is not hard-coded. If it is hard-coded, then we need to hard code all the time. We take
what changes which is the shape of windows and tables and leave those that are not
which is the generation of the actual windows and features as we see when we open up
the application menu.

This thinking of reusing to avoid repetitive work is a very powerful idea. Many of our
top developers in the community project often apply this whenever they are coding
new stuff or reviewing old ones. It is like building bigger and more powerful machines
to do work. We have to leave the use of old shovels and buckets, and create to use gears
and propellors. From this point onwards you can keep your mind open to observe more
patterns in use. The next topic about ASP is exactly using the same concept but on a
different context.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 84
3.9 ASP
In order to make Adempiere ASP (now called Saas or On-Demand) friendly it was
implemented a way to show/hide specific functionality by client (tenant). This feature
is contributed by Carlos Ruiz and the following are adapted from his wiki page work on
it[6].

Configure Modules and Levels

• Now you can define modules (i.e. Sales / Purchase / CRM / Accounting ...)

• And for each module you can define levels (i.e. Beginner / Full ...)

• Then you can define in a detailed way the functionalities "covered" by each level.
• You can define the supported Windows, Tabs, Fields (optionally you can define to
cover all the fields on a tab), Forms, Tasks, Process, Process Parameters and
Workflows.

Figure 3.12 Generating Specifics to Client Preferences

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 85
Subscribe Client to Level and configure Exceptions
Then you can define which modules/levels a client is subscribed to. And define specific
client exceptions as shown below.

Figure 3.13 Defining ASP Exceptions

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 86
Define if Client use ASP
Finally you must define the client to use ASP functionality (just show subscripted
functionalities):

Figure 3.14 Checking Client Use of ASP

WARNING: You must previously define the modules/levels and subscribe the client to
a level - if you don't do that your menu will become empty

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 87
3.10 SaaS Revisited
This ASP or Application Service Provider concept is now reincarnated from its fallen
past as something sexy sounding such as SaaS (Software As A Service) which is more
technically true, and even Application On Demand which seems to be more poetic
sounding and impressive enough to shout out in a brainstorm meeting.

There is a another concept phrase floated by ISPs (Internet Service Providers) a long
time ago, which seems to ring well the ASP rhythm, is Apps On Taps that you do not
hear often anymore. Hope you get the idea of what is going ON. So, question is how hot
is in our case, ERP On Demand getting? A simple yahoo check says it is.

Is it Outsourcing?
But as these concepts stem from the disastrous need of throwing out the bathwater
every time a baby is washed, they fall under a broader category called Outsourcing.

We then can have a cursory examination of what can particularly in this area of ERP
happens to pose an even higher risk than in-sourcing.

ERP as we know it is not something you can outsource or give away. It is not non-core
IT activity. It is core business subject matter and that is core.

The expectations of customers of ERP to think they can remove the pain away probably
will give On Demand solutions an intial boost, but as the example of SAP associated
CRM On Demand solution SalesForce.com has shown dramatic flight patterns when its
profits plunge. What more inadvertently giving away its customers' list.

It is a Channel, Stupid
That is what Howard Smith seems to say in his blog. It is still not a service. And service
takes a different drawing board. It takes business concerns, which takes content, which
takes expertise, which takes attention, which takes another business all together.

It is like what I often tell OS pundits that Free doesn't mean Free. So now I have to
introduce anoher phrase, Outsourcing your TCO doesn't mean you do not have another
bigger TCO.
Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering
P a g e 88
3.11 Service Oriented Architecture
One of the important and wise software engineering strategy is to have an application
suite ‘loosely coupled’ among its components and functionals. This is to avoid, well
‘tight coupling’ which as the phrase goes can mean cumbersome and unwieldy
structural design. One of the loosely coupled implementation approach is Service
Oriented Architecture or SOA[7]. Such an architecture is more distributed or
distributable where scalability is easy and allows n-tier server arrangement, rather than
just 2 or 3-tier limitations.

ADempiere is beginning to implement such a concept using what is commonly known


as ‘Web Services’. The following is adapted from Carlos Ruiz’s work that has completed
upon an earlier start by 3E of Poland. Web Services is very exciting as we are also using
it to adapt other projects such as OpenBravo’s POS (bought from TinyERP POS) instead
of coupling it restrictively. Also refer to an earlier implementation example done by Jeff
Davis in his blog[8].

How to install and test


Currently this project is not yet integrated into stable trunk and can be located as a branch in
SourceForge.net project SVN repository[9].
In order to test it you must follow this steps:
1. Run the scripts provided in 3E_WebServices/migration according to your database
a. WS001_WebServices.sql - creates the tables and windows to define the web service security as
shown in Adempiere Web Services Security
b. WS002_WebServicesDefinition.sql - creates the definition of the currently supported web
services and methods
c. WS003_WebServicesConfigGardenWorldSample.sql - create role, user and two sample tests
for testing web services with GardenWorld
2. Download the latest release of ADInterface from sourceforge.net here
a. Or follow the direct link: 3E_WebServices_20090320.tgz
3. Go to your adempiere installation home, i.e. cd $ADEMPIERE_HOME
4. Stop the app server (RUN_Server2Stop)
5. Uncompress the downloaded file, i.e. tar xvzf DIR_DOWNLOAD/3E_WebServices_20090320.tgz
a. Warning, this will overwrite build.xml and lib/adempiereAll.xml - be careful in case you
have modified these files
6. RUN_setup
7. Start the app server (RUN_Server2)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 89
8. Test if the webservices are installed navigating to the address http://your_server:your_port/
ADInterface/services/ADService?wsdl
a. i.e. supposing you installed in localhost using port 80 as web: http://localhost:80/
ADInterface/services/ADService?wsdl

NOTE: All test have been done in a patched 342s version.

Development Guide
You can find instructions about how to add datatypes and/or web services in the repository file
Notes/HowToAddNewWebService.txt

Test Scripts
soapUI
1. Tested the model webservices using soapUI tool. Excellent tool - the tests are working ok.
2. You can find test project for soapui in svn repository AdempiereWebServices-soapui-project.xml

In order to use it you need to change the protocol, hostname and port according to what you want to
test ( search the https://localhost:8443 string and replace it properly with your installation
protocol://host:port )

Shell script testing


1. You can find some scripts to test (using wget) in the repository directory testScripts

Oracle pl/sql testing


1. Warning: obsolete test case, the message needs to be upgraded to the new web service definition
2. There is also a sample of a pl/sql function that calls modelSetDocAction in the repository file
Notes/HowToCallWebServiceFromOraclePLSQL.txt

Eclipse testing
1. I tried testing with Eclipse Ganymede JEE version.
2. Running from Web perspective, you can try Run -> Launch the Web Services Explorer
3. The web services are properly discovered using the WSDL button and entering the URL of the
server wsdl described above.

Unfortunately the web services can't be tested from eclipse. It seems eclipse is not supporting the rpc
style of web services, it's sending the message formatted as document style.

Web Services

Model Oriented Web Services (ModelADService)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 90
WSDL: ModelADService.wsdl

Model oriented web services has a different approach to run things on ADempiere. They need login
data on each request, opening a session, executing its operation and closing the session. They are not
intended to replicate the UI functionality, but to allow executing common operations within
ADempiere.

All these web services need login data:


• ADLoginRequest (user, pass, lang, ClientID, RoleID, OrgID, WarehouseID, stage) - note stage is not
used here.

All these web services receive a serviceType parameter. This is configured in the security layer
explained in Adempiere Web Services Security. The parameters are checked (and modified if
necessary) against the definition of the serviceType.

Configuration and Security


Model web services are highly generic - so they need an additional security layer in order to ensure
the server security is not compromised.
If you want to learn more about how to configure web services and security in Adempiere dictionary
please read below after this: ADempiere Web Services Security

setDocAction
This web service is intended to trigger a change in document action, i.e. complete a material receipt,
prepare a purchase order, void an invoice, etc.
WARNING! - This web service complete documents not via workflow, so it jump over any approval
step considered in document workflow. To complete documents using workflow it's better to use the
runProcess web service.

Parameters:
• serviceType
• tableName
• recordID
• docAction

Returns:
• StandardResponse (Error Message, IsError flag, RecordID)

Process:
• Login and create session (it returns proper message if it can't login)
• Get the record given the tableName and recordID (it must be a document table, it
must have an associated Model class implementing DocAction interface)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 91
• Call the method corresponding with the newDocStatus (i.e. prepareIt, completeIt,
voidIt, etc)
• Returns any message, and flag the IsError flag accordingly

runProcess
This web service is intended to run a process, or raise a process that starts a document workflow.

Parameters:
• serviceType
• AD_Process_ID
• AD_Menu_ID - not used
• AD_Record_ID
• DocAction (used if the process is a document workflow)
• ParamValues (optional, set of DataRow)

Returns:
• RunProcessResponse (Error, Summary, LogInfo, Data, IsError, IsReport,
ReportFormat)

Process:
• Login and create session (it returns proper message if it can't login)
• If the process is a document workflow, set DocAction according to the parameter
• Executes the process pointed by AD_Process_ID
• Fill the return message and return accordingly to what the process must return

getList
This web service is intended to get data from a list (reference list or reference table)
Parameters:
• serviceType
• AD_Reference_ID
• Filter - optional

Returns:
• WindowTabData (DataSet -> DataRow array -> DataField array -> pair of Column
and Value)
Process:
• Login and create session (it returns proper message if it can't login)
• Get the list table, columns, where and order by
• Apply the filter
• Fill the return message with values of the allowed output columns

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 92
createData
This web service is intended to create one record on a table. The table and allowed input columns
must be configured in the serviceType.
Parameters:
• serviceType
• TableName
• RecordID - not used here
• Filter - not used here
• Action - must be Create
• DataRow (DataField array of Column+Value pairs)

Returns:
• StandardResponse (Error Message, IsError flag, RecordID)

Process:
• Login and create session (it returns proper message if it can't login)
• Create a new record on the desired table
• Set the columns
• Invoke the adempiere persistence engine to save the row (this implies calling
automatically before/after triggers and model validators)
• If successful, fill the RecordID of the response
• Returns any message, and flag the IsError flag accordingly

updateData
This web service is intended to modify one record on a table (accessed by ID). The table and allowed
input columns must be configured in the serviceType.

Parameters:
• serviceType
• TableName
• RecordID - required
• Filter - not used here
• Action - must be Update
• DataRow (DataField array of Column+Value pairs)

Returns:
• StandardResponse (Error Message, IsError flag, RecordID)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 93
Process:
• Login and create session (it returns proper message if it can't login)
• Read the record from the desired table using the recordID
• Set the columns
• Invoke the adempiere persistence engine to save the row (this implies calling
automatically before/after triggers and model validators)
• If successful, fill the RecordID of the response
• Returns any message, and flag the IsError flag accordingly

deleteData
This web service is intended to delete one record from a table. The table must be configured in the
serviceType.

Parameters:
• serviceType
• TableName
• RecordID - required
• Filter - not used here
• Action - must be Delete
• DataRow - not used here

Returns:
• StandardResponse (Error Message, IsError flag, RecordID)

Process:
• Login and create session (it returns proper message if it can't login)
• Read the record from the desired table using the recordID
• Invoke the adempiere persistence engine to delete the row (this implies calling
automatically before/after triggers and model validators)
• Returns any message, and flag the IsError flag accordingly

readData
This web service is intended to return values from one record on a table (accessed by ID). The table
and allowed output columns must be configured in the serviceType.

Parameters:
• serviceType
• TableName
• RecordID - required
• Filter - not used here

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 94
• Action - must be Read
• DataRow - not used here

Returns:
• WindowTabData (DataSet -> DataRow array -> DataField array -> pair of Column
and Value) - just one record

Process:
• Login and create session (it returns proper message if it can't login)
• Read the record from the desired table using the recordID
• Fill the return message with values of the allowed output columns

queryData
This web service is intended to query records on a table (accessed by conditions on columns and
filter). The table, allowed input columns (conditions) and allowed output columns must be
configured in the serviceType.

Parameters:
• serviceType
• TableName
• RecordID - not used here
• Filter
• Action - must be Read
• DataRow - to define the conditions of columns

Returns:
• WindowTabData (DataSet -> DataRow array -> DataField array -> pair of Column
and Value) - zero, one or several records

Process:
• Login and create session (it returns proper message if it can't login)
• Query the records from the desired table using the conditions on columns and filter
(and applying the access security defined for role)
• Fill the return message with values of the allowed output columns

UI Oriented Web Services - ADClient.exe (ADService)

WSDL: ADService.wsdl

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 95
WARNING: These web services are very generic and still not configured a security layer, in the
sample data and migration scripts these web services are closed, opening these web services can
represent a security hole (i.e. a user could get the SuperUser password)

3E developed lots of UI oriented web services, and they're ready to use and test with their ADClient
tool that you can download here ADClient_0.7.6.zip. In order to test, you will need to activate the
web service ADService (not recommended in production).

According to the instructions on their page you must download ADClient package (2 mb), unzip it in
choosen dir, edit ADClient.ini file and set up service host (or leave it unchanged for localhost) and
run ADClient.exe.

These web services are oriented to UI, this is, they create a session and environment to work as if you
were in Adempiere swing client. You can open windows, navigate data, change, remove, run
processes, etc.

The UI oriented services already included are: login, isLoggedIn, getADMenu, saveLocation,
setDocAction, getLookupData, updateDataRow, getDataRow, ignoreDataRow, addNewDataRow,
getProcessParams, getLocation, runProcess, getLookupSearchData, getVersion, saveDataRow,
deleteDataRow, getDocAction, getADWindow, refreshDataRow, getWindowTabData

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 96
3.11a Web Services Security
Security Concerns
There may be security concern as an external URL call can access an ADempiere SOA.
This is resolved by securing the server side to validate the calling service. The next
article again from Carlos Ruiz explains how it is done.

First you must register the web services:

3.11a-1 Web Service Defintion Window

Methods

And then you must register each method from the web service. In the 2nd tab, Web Service Method:

3.11a-2 Web Service Method

Security
Model web services are highly generic - so they need an additional security layer in order to ensure
the server security is not compromised.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 97
It's important then to allow fine configuration of the allowed values for each method, this is achieved
configuring web service types in a client basis.

Role and User


Firstly is recommended you create a specific role and user (or several) just for the web services, the
role must be manual, and you must allow access just to the processes needed. Not windows, not
tasks, etc.

3.11a-3 Web Service Role

Sample - Process Invoice web service

Web Service Types


In web service type you configure types of the generic web services, for example you can configure a
web service to call the process that starts the workflow for process invoice.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 98
3.11-4 Web Service Type

Parameters
This web service receives some specific parameters, so we configure here if the parameter can be used
freely (Free), or if the parameter must have a constant value (Constant).

3.11a-5 Web Service Type Params

Access
And then you must configure the Access to allow execution from the proper web service role:

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 99
3.11a-6 Web Service Type Access

Sample Create BPartner web service - using Fields input


• A more complex configuration must be done for the methods that pass and receive data rows.
• In this case you must configure the allowed input columns, and/or the allowed output columns.
• Example of methods that receive data row are createData, updateData, queryData.
• Example of methods that return data row are readData, queryData, getList.

Web Service Type Using Fields Input


Again, you must configure the Web Service Type. But in this case you need to specify the table
associated with the web service:

3.11a-7 Web Service Type

Parameters Allowed
You also need to configure the constant and free parameters:

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 100
3.11a-8 Web Service Type Params

Fields Input
And here you must configure the allowed columns to pass in datarow.
This is a really important step, for example allowing modification of the password on user table it can
compromise seriously the security of the server.

3.11a-9 Web Service Type Fields Input

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 101
Openbravo POS integration web services
In order to allow integration with Openbravo POS there is a Proof of Concept with the web services
ExternalSales and WebService.
The Openbravo POS messaging is using RPC/Encoding, currently xfire doesn't support that, so for
the testings I needed to modify some openbravo classes to read/write RPC/Literal. It's expected that
xfire will support RPC/Encoding soon, meanwhile we can test with modified POS. This is in alpha
status - still not working.
Just developed and tested the authentication, and checking how to messages are transported.
Currently the message receiving arrays of orders, bpartners, products, etc. Is not implemented.

RoadMap
• Implement a webservice that can combine all of the previous within one single login and
transaction (this would need to set values on context variables, to reuse in later messages)
• Reuse login between different calls
• Complete Openbravo POS integration

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 102
3.12 Status of OpenBravo POS Integration
To give you an idea of the challenge when it comes to integrate 2 open source projects
together, below is a discussion thread [10] from our community brains, Carlos Ruiz
(Colombia), Colin Rooney (Ireland) and Low Heng Sin (Malaysia) :

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 103
(cont’d from previous page)

(cont’d next page)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 104
(cont’d next page)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 105
(cont’d next page)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 106
(cont’d next page)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 107
(End of thread to-date. Follow online[9] for latest updates)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 108
3.13 Cloud Computing
The parent project of ADempiere, Compiere has started using this latest craze in large
scale enterprise computing. Users that suscribe to this virtual service will have its
application in a perfect mode of guaranteed availability, scalability and dependability
due to the ‘cloud’ setup in a grid of computer hardware, networked and portable,
without concern of hard settings and their temporal limitations. The concept is actually
simple once set up. Any virtual machine of which ADempiere also has a version of, can
exist within this ‘cloud’ and be restored or swapped without setting up again its
underlying platform. It can exist perpetually and more importantly scaled ad infinitum
without ever been restarted for maintenance. Only its underlying platform of hardware
is maintained, replaced or upgraded while its virtual passenger’s existence continue, by
moving it seamlessly to another temporal or upgraded hardware. The accesibility is
switchable to the new underlying setup giving the impression that the application is
always alive without knowing about its underlying host’s condition.

Cloud computing seems like a major jump in application service, but like Ajax, it is
more of an old technology been exploited to the maximum. It is in a way taking the idea
out of what the JVM did to programming language. It allows higher distributability for
the more global audience to use. Better management of active sessions of the cloud
application will give more users the feel of desktop computing power over the web.

Cloud computing allows or overcome limitations that bulky applications usually face
such as CPU or memory size as such items are scalable and the application portable
from one hardware setup to another. ADempiere also has a virtual machine version
called the AVA[11] and thus can be easily placed in a cloud environment.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 109
3.14 OSGI Plugin Components
OSGI is a latest craze hitting our project and you can say that it is another form of
pattern thinking which is in the way modules or verticals are shaped in the application.
The idea is to make every module in a standard format that is pluggable and thus easily
deployed. Take the analogy of a car wheel. The way it is shaped makes it easy and fast
to be fixed and taken off or replaced. There is no welding, hard wiring or banging to
change it.

In software engineering, it has become a headache to code without such designs or


standards or reusable pattern. Now with OSGI (www.osgi.org) which is termed as The
Dynamic Module System for Java™, we can do away with welding and scaffolding
work and focus more on the business module creation. The following is the work of
Joerg Viola of Object Code GmBH, Luenen City, near Dortmund, Germany[12]. I have
the pleasure of visiting him last June 2009 before the Berlin Conference and he and his
company played a great host putting me up in their office and his lovely home for 2
nights in order to learn more about this OSGI. I found out that once done, it is so simple
that the stub for a new OSGI can be generated in 2 minutes or a few clicks! That is the
power of knowing compared to not knowing.

The status about this OSGI works is that it is now proven as a POC with a few stubs
created for the ADempiere patterns to now behave as plugins, such as 2Pack,
ModelValidator and Patch. More of these wonderful artifacts by themselves later. For
now, this OSGI plugin mechanism is one big step towards scalability of the whole
application to be like the figure above where verticals can come into the horizontal ERP
system more easily than ever.

Eclipse Equinox Plugins in ADempiere


Eclipse Equinox (http://www.eclipse.org/equinox) is an implementation of OSGi R4. Moreover, it
provides applications with a plugin mechanism based on extension points and extensions satisfying
them.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 110
Integration with ADempiere has only truly started with the proofs in this page by Joerg Viola of
ObjectCode GMBH working on the shoulders of Schmidt András's earlier Felix usage and Low Heng
Sin's advice to use Equinox instead.

Currently, an alpha demo is available. The vision is to integrate it into Adempiere core an have every
further extension be delivered as a plugin.

Technical documentation
The integration consists of four components, implemented each in its own project in an eclipse
environment.

ADempiere patch
This patch currently is very simple. It consists of

• The interface IExtension, a factory for IExtensions called Extension and two implementations:

• The DefaultExtension contains code extracted from ADempiere core classes.

• Equinox contains code to delegate the functionality to equinox plugins.

• Which extension is used, depends on a prefix of e.g. the given classname: osgi://
formClassName would use Equinox whereas formClassName would use the
DefaultExtension and thus provide a clean fallback

• Patched core classes, namely:

• class org.compiere.Adempiere: Start all extensions

• class org.compiere.apps.form.FormFrame: Form class loading

• class org.adempiere.util.ProcessUtil: Process class loading

• class org.compiere.model.GridTab: Callout class loading

• The Equinox Extension starts the Equinox container

• It does so in a seperate thread, because the platform modifies the context classloader

• It fires up an OSGi console on port 1234, so that you may connect to it via telnet and see
whats going on

• It then asks for the so-called "host service", an OSGi-Service gatewaying requests from the
patched adempiere core into equinox

• A lib-folder that must be copied to the runtime classpath

• In fact, I don't like the way, libraries are re-packages during Adempiere install

• Nevertheless, the Equinox OSGI jar must stay intact in order to work, so I switched to only
deploy the patch itself, not the supporting libraries re-packaged

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 111
• An build file that, after having setup a build.properties does the re-packaging and
deploying into an installed JBoss.

ADempiere Extension
• This is an extension fragment to the system bundle (OSGi slang...)

• It provides the ADempiere classes to the classpath of all plugins

• It is merely declarative and contains no code

ADempiere Equinox bundle


• This is a bundle that connects plugins to the ADempiere internals

• It will provide the extension points for ADempiere

• Currently, there are

• ModelValidator

• Form

• Callout

• Process
• It implements and registers the so-called "host-service" that receives requests from the adempiere
core and dispatches them to bundles, typically via extension points.

• It implements and registers the "dictionary service", that uses PackIn to import PackOut.xml.

• It provides a Plugin base class, AbstractAdempierePlugin, that handles install and startup:

• If the plugin is started for the first time:

• If /META-INF/PackOut.xml exists, it is PackedIn

• If not, the plugin is manually registered as an imported package

• The method install() of the bundle is called

• The Method start() of the bundle is called (this substitutes start(BundleContext) from OSGi)

• On stop, The Method stop() of the bundle is called (this substitutes stop(BundleContext) from
OSGi)

• So, if you want a full re-install of the plugin, you must increment the version number or delete the
corresponding entry in "Imported packages"

• Caution: Name and Version in the bundle header and in PackOut.xml must correspond!

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 112
The TestPlugin
• This is a very simple plugin testing the above

• Its activator does nothing

• It provides extensions to the extension points ModelValidator, Callout and Process

• The extension consists of a ModelValidator class (you wouldn't have thought so, would you?)

Basic Setup
This Basics and JBoss Setup will make use of the WebUI layer. Other Setups will target Java Client,
WebStart and so on.

Basics and JBoss Setup


• Install an eclipse, checkout the ADempiere trunk (as adempiereTrunk) an install it.

• adempiereTrunk/adempiere/Adempiere/jboss will then contain a jboss ready to run

• The Code is in this branch: /branches/osgi/


• There are several projects to be separately checked out aside adempiereTrunk

• copy Adempiere-patch/build.properties to build-local.properties and set the path to the adempiere


project

• at Line 103 of build.xml change AdempiereOriginal.jar to Adempiere.jar

• at Line 112 of build.xml change webuiOriginal.war to webui.jar

• run Adempiere-patch/build.xml

• It will populate your Adempiere JBoss with the patch, all required equinox library and
configurations

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 113
Equinox Manifest
• Open AdempiereEquinox/META-INF/MANIFEST.MF (make sure you are in the J2EE Perspective)
Figure 3.15 Manifest.mf of Adempiere Equinox

* NOTES
1. The tab "extension points" contains the ModelValidator point.
2. Click on the third icon in the header ("Export deployable...") or in the menu File/Export/Plugin
Development/Deployable plugins and fragments.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 114
Deploying

Figure 3.16 Exporting Plugins


* NOTES
1. Ensure build.properties has right settings, such as - jars.extra.classpath = ../../adempiereTrunk/
install/build/Adempiere/lib/Adempiere.jar
2. Select AdempiereEquinox, AdempiereExtension and the TestPlugin for deployment
3. Choose as destination directory: <path to adempiere project>\adempiere\adempiere\Adempiere
\jboss\server\adempiere\deploy\adempiere.ear\lib
4. Click Finish
5. In the ear deployment in JBoss, you should have a lib folder containing jar, a configuration folder
and a plugins folder with the three plugins from above

Start Application Server


• Start your JBoss
• Watch out for the lines:

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 115
INFO [STDOUT] Starting Equinox...

INFO [STDOUT] Listening on port 1234 ...

INFO [STDOUT] Adempiere Host Bundle started

INFO [STDOUT] Got Val Engine: ModelValidationEngine[Validators=#1, ModelChange=#1,


DocValidate=#1]

INFO [STDOUT] ModelValidator on: AD_User

INFO [STDOUT] Hello World!!

Congrats! Your equinox container started, opened a telnet port, started the Host Bundle which in turn
got a ModelValidation engine, found the TestPlugin listening on Table AD_User and registered it on
the Engine.

Test
Now fire up the ZK Web UI, login as SuperUser, Role System Administrator and change any field
value in the Window User.
* You will see:

INFO [STDOUT] ModelChange 2 on AD_User:1000000

INFO [STDOUT] ModelChange 5 on AD_User:1000000

* Phew! ADempiere plugin via equinox is working!


* Now open TestPlugin/META-INF/MANIFEST.MF

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 116
Figure 3.17 Extensions View of TestPlugin

On the extension tab, you can see why it listens on AD_User: It was declared to the host bundle in the
manifest!

Other Setups
Here we see the deployment on other clients in use such as the Java Swing Client, WebStart client on
LAN and other forms of plugins.

Swing Client Setup


If you have successfully installed Equinox into your JBoss, making it available in the Swing Client is
easy:
1. run Adempiere-patch/build.xml
a. Use the target dist-client for instrumenting your swing client
2. run RUN_setup.sh in order to re-package the jars again
3. Repeat the plugin deployment above, using $ADEMPIERE_HOME/lib destination directory
4. ... and eventually a nasty step: Edit the script $ADEMPIERE_HOME/lib/RUN_Adempiere.sh
(or .bat) locate the line where the CLASSPATH is set up and add $ADEMPIERE_HOME/lib/
org.eclipse.osgi_3.4.2.R34x_v20080826-1230.jar to it.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 117
WebStart Setup
Equinox is useable in a WebStart-Deployment also! Nevertheless, currently it is tricky to configure,
which plugins are to be deployed with the Webstart Client. Do the following:

1. Repeat the plugin deployment above, using Adempiere-patch/src/webstart destination directory


a. Edit Adempiere-patch/build.xml
b. Add the plugins you want in the obvious part of the target dist-webstart
2. Edit Adempiere-patch/src/webstart/conf/adempiere.jnlp
a. Add the plugins you want in the obvious way in the resources part
3. run Adempiere-patch/build.xml
a. Use the target dist-webstart for instrumenting your swing client
* Restart JBoss

Build your own plugin


* simply create a new eclipse plugin project
* use AdempiereEquinox as required bundle
* register a ModelValidator class as the extension
* deploy the plugin to JBoss as above
* restart JBoss (or use the telnet session an stop/start the host bundle)

Form extensions
It is now possible to deploy swing forms via a plugin. To do this, create a plugin and specifiy some
dependencies:

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 118
Figure 3.18 Dependencies View of DATEVPlugin

(DATEV is a common localisation product specific to German Accounting market and is integrated to
ADempiere by Metas AG of Bonn).
Switch to the extension tab, click add and choose the AdempiereEquinox.Form extension point.
Right-click on the new extension and choose New.../client. Create or select the class (must be of type
FormPanel).

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 119
Figure 3.19 Extensions View of DATEVPlugin

Deploy the plugin. As usual, as SuperUser create a new Form, specifying the class as above and a
new Menu entry. Try it!

WebForm extensions
This works essentially the same as for Form above, extending the point WebForm of course.
Nevertheless, two things are different:
Since plugins essentially are deployed in the EJB layer but must have access to classes in the web
layer (org.adempiere.webui.* and org.zkoss.*), the JBoss WAR classloader has to be turned off. This is
a drawback since we no longer have classpath separation between web- and ejb-tier. You do this by
switching the attribute UseJBossWebLoader to true in $JBOSS/server/adempiere/deploy/jboss-
web.deployer/META-INF/jboss-service.xml.
You have to import several additional packages in your plugin, at least:
org.adempiere.webui.component, org.adempiere.webui.panel,org.zkoss.zk.ui and
org.zkoss.zk.ui.event.

Other Possible Requirements


If we deploy plugins to a server, we should be able to choose which plugins are applied to certain
situations - for example - if accounting methods (allowed under various IFRS) were plugins, then

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 120
each adempiere client would need to select or configure which plugin they use for each accounting
schema. Therefore, we would need to be able to have a plugin lookup field, and select the plugin and
perhaps a method for each feature (similar to current class callouts).
We might want to define plugin types - where we can have say accounting method plugins, which
implement accounting methods and can be selected from the accounting method field on the
accounting schema tab/window. i.e. a way of filtering plugin selection to only valid types.
We might need to see a list of available and installed plugins - propose available plugin list is
retrieved from the repository and installed plugin list is stored in a table.
We would need to configure plugins - e.g like sysconfig - suggest extending sysconfig for core /
plugin - perhaps we could have a config interface which implements a config form / window in a
plugin implementation (template) .

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 121
Summary
1. Today software needs to be robust and short time to deliver on its implementation.

2. Compiere’s framework is also a RAD framework to quickly prototype a user case


before deciding on a full fledge investment of resources on an ERP implementation.

3. ADempiere’s community constantly build a huge knowledge base for easier adoption
learning curve to the open public.

4. Open source allow the standing on the shoulders and reuse previous achievements
without patenting obstructions, but yet maintaining IP credits to the authors.

5. The Compiere parent contribution accounts for many wonderful features that are
unbeatable in the Open Source market.

6. OfBiz is another serious contender for ERP application but it is not its main forte of
focus.

7. Due to the high failure rate of ERP implementations, users out there are looking at
better options.

8. Meta-data approach of not touching source-code in making system changes ensure a


zero introduction of coding bugs into the software.

9. Compiere has offered its application using Cloud Computing but ADempiere opens
up with contributions to make it ASP ready and having its own free virtual machine.

10. SOA and Web Services are also implemented in ADempiere that comes with added
web services security.

11. OpenBravo has bought over a POS from TinyERP which is also being integrated into
ADempiere as a web services component.

12. OSGI allow advanced componentisation of the ERP modules particularly the large
verticals specific to industry.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 122
Quiz
1. What should a good programming framework be?

2. Who are the best people to determine a software acrhitecture? Why?

3. How can the ADempiere software be improved?

Glossary

Term Description

Pattern In software context is a reusable template to resolve certain


programming tasks

Framework A pattern of codes that encapsulate a generic application to be


reused and extended from

Vertical App A module or functionality that covers a specific discipline such as


shopfloor manufacturing that can sit on a horizontal application

Horizontal App An application that is generic fulfilling a broad range of needs such
as an ERP system. Usually configurable to specific needs.

On The Fly Refers to the ability to launch some dynamic configuration or


seemingly programming activity without coding

RAD Rapid Application Development is a buzz word for tools that can
help developers program without scafolding or boilerplate work

Interoperability The ability for a piece of software or hardware to communicate


with each other without further programming

Plugin A component that is created separately but fitting to another whole


application to operate further.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 123
References
1. http://opensource-pragmatist.com/tag/erp/

2. http://ofbiz.apache.org/feature-list.html

3. http://theoserp.blogspot.com/2007/01/finalists.html
4. http://www.technologyevaluation.com/Research/ResearchHighlights/
FreeOpenSource/2004/09/research_notes/VN_FS_JC_09_09_04_1.asp (free
registration)

5. http://java.sun.com/blueprints/patterns/catalog.html

6. http://www.adempiere.com/index.php/ASP
7. http://en.wikipedia.org/wiki/Service-oriented_architecture

8. http://jeff-davis.blogspot.com/2007/12/soa-essentials-part-1.html (see also part 2)

9. http://adempiere.svn.sourceforge.net/viewvc/adempiere/branches/
3E_WebServices/migration/

10. http://sourceforge.net/forum/forum.php?thread_id=3162659&forum_id=611158
11. http://www.adempiere.com/index.php/ADempiere_Virtual_Appliance_Install

12. http://www.adempiere.com/index.php/Equinox_Integration

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 124
Chapter 4 - Handling Source

Learning Objectives
By the end of this chapter, the student shall be able to:

1. Explain the basics and advantages of using Java as a programming language;

2. Describe one way of getting the SourceCode of ADempiere;

3. Able to import the sourcecode into Eclipse IDE;

4. Able to handle the sourcecode from clean build to deploying binary.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 125
Introduction
As Linus Torvalds was once acredited with the words, “Show me the codes”, opening
up sourcecode has now become a norm. Even previously very proprietary and patent
making vendors such as Microsoft and Oracle are releasing big chunks into cyberspace.
But having the code is only part of the story. Knowing and able to handle it is another
even bigger part of the story. Today we have unlimited access to unlimited amount of
information and code. The challenge is daunting. It involves a very steep non-stop
learning on our part.

In this chapter I hope to gently introduce to the uninitiated what to expect when
handling code and what it means to have open source on your lap. What do you do first
to get the sourcecode? Where is it stored? How is it downloaded? What do we look for
inside the code? What can I start to modify to show my part? That will lead you to
complete the cycle and make you not just a consumer as most people are today, but a
prosumer - producing while consuming.

We will also try to understand if the choice of a programming language is important as


Compiere’s family is written in Java and there are new emerging more sexy languages
such as Python, Ruby and Groovy. Why not C++, Php or Cobol? What happened in the
future? Will whatever I learn or create today becomes obselete then?

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 126
4.1 Why Java?
There are lots of comparison done and still going on about the pros and cons of Java
versus other latest programming langauges[1]. For programming a complex business
application such as an ERP system, I would support the use of Java due to the
following:

1. It is really cool to be known as a Java developer;

2. Compiere was already on Java;

3. I didn’t know Java before and Compiere started me going;

4. I don’t really know other languages except BASIC and COBOL so I cannot say how
much more suited Python, Ruby or VisualBasic is compared to Java.

So I will rely more on googling to get the answer to the question above. Then we can
provide a more objective analysis rather than relying on hunches and holy faithfulness
to everyone’s own religion.

There are already very common arguments on why Java is best and I will list them
down here so that you can keep them buried somewhere just in case you are
confronted by fanatics from the other side:

1. Java has industry acceptance. You cannot go wrong with Java owned by Sun, bought
over by Oracle and Microsoft having its own Java flavour[2]. No one will hate you
(perhaps envy is more accurate) more than they find it hard to learn it.

2. Java has maturity. It has lots of ready made libraries, tested through time for reusing.
You can use this argument well against newly minted languages as they are bound to
be lacking relatively in common APIs and well, not tested through time. You
wouldn’t want to risk that for sure.

3. Java is more scalable. Now you have to prepare to run or duck as opponents are most
likely to grab a chair and throw at you. Well do not take our word for it, this is what
you have to say to them. Check it out. And understand what we really mean by
scalable. We do not mean the coding but the quantity of people that can really work
Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering
P a g e 127
on a single project. Java strongly-typed rules and strict object parametering forces
developers to be more disciplined (besides smarter as it just take a donkey to learn
Php - now you really have to run!) in that another developer working or extending it
will not be stopped by a bunch of spaghetti coding (description used on what will
happen when you are lazy and rely too much on Php).

4. Java has reusability. Perhaps the most powerful idea to address the software crisis.
Java is object-oriented, allows building blocks to grow for reuse by other builders.
Even though other top new languages are staking a claim in the same OO territory
such as Python and Ruby, they also incoperate java adaptors such as Jython and
JRuby respectively, in order to appease the java librarians.

Now let us quickly appease the other side with the suspicions many have against using
Java[3]:

1. It is hard to learn. Actually it is because there are bad teachers. Anyhow the reason for
creating Java was because C++ was very difficult to learn. So hope this set your spirits
higher to take on Java.

2. Java is slow. I do not dare to say ‘slower’ because for that you need more proof and
that is hard to get as well as being very subjective. Benchmark testing has its own
story as it really depends on what you are testing it for[4].

In conclusion I like to urge students to take on Java more so for its vast educational
potential, particularly just by listening to how others debate it out[5]. You get to learn
things seriously and become really smart for having mastered Java one fine day.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 128
4.2 SourceCode Layout
There are about 3.1 million lines of code in ADempiere[6], counting 17,908 items at 1.88
GB size as at July, 2009. Based on Java packages, it is organised into sub-projects folders
or directories for easy browsing and maintenance. The parent project Compiere was
using JBuilder in the early 2000s to view and edit the codes. When Eclipse became more
prominent around 2003, that became the IDE of choice. The following is the project
layout as seen from Eclipse, arranged side by side to show all of its contents on one
page.

Figure 4.1 Project Layout of ADempiere SourceCode

Its current layout structure as shown above has not changed since forking from
Compiere with perhaps only new ones such as Posterita, JasperReports and migration
works.
Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering
P a g e 129
4.3 Checking Out Source
To get the latest sourcecode into your environment whether it be for scrutinising or
modifying or compiling the latest from the ADempiere project, you have to setup
Eclipse or Netbeans in your PC. Then through the IDE you access the SVN repository of
http://sourceforge.net/projects/adempiere to check it out.

To have the SVN client working you can refer to Figure 2.1 in chapter 2. Once that is
done, you can call up the SVN Respository Exploring perspective. It is here where we
put in the url connection string: https://adempiere.svn.sourceforge.net/svnroot/
adempiere. Once that is validated, we can start a checkout by right clicking on the
repository item, and select checkout command.

Figure 4.2 Checkout Steps from SVN

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 130
Figure 4.2b Checkout Steps from SVN (cont’d)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 131
After clicking on the Finish button above, the progress console view will show activity.
If it breaks due to some trouble with the web connection, you need not checkout again.
Just go to the project and right click to select Team and select Update so that it resumes
where it stopped. Do this updating till it says there is nothing fresh to update. That
means you have reached the end of the checkout process.

Figure 4.3 Updating the project source

You can do this updating whenever you notice there has been new commits done by
others from the SVNLog maillist tracker. In this way your local project instance will be
up-to-date as the trunk’s instance.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 132
4.4 Deploying from Source
In order to take the source to a user environment, it has to be compiled first. That is
done with the /sourcecode-trunk/utils_dev/RUN_build.sh
Build
If you have not done so, you can download the source code from the sourceforge
subversion repository:
http://adempiere.svn.sourceforge.net/svnroot/adempiere/trunk
You can also refer to tags and branches if you want to download and build a different
version.
After downloading the sources with a subversion client (i.e. Download in C:
\srcAdempiere\trunk) you need to edit the file utils_dev/mybuild.properties (this file
can be copied from utils_dev/build.properties) and set the following variables (you
need to replace the directories to those for your environment):
1. env.ADEMPIERE_SOURCE=C:/srcAdempiere/makeinstaller
2. env.ADEMPIERE_ROOT=C:/
3. env.ADEMPIERE_HOME=C:/Adempiere
4. env.ADEMPIERE_INSTALL=C:/srcAdempiere/Installers
5. env.ADEMPIERE_VERSION=ADempiere
6. env.ADEMPIERE_VERSION_FILE=Trunk
7. env.ADEMPIERE_VENDOR=ADempiere
8. env.ENCODING=UTF-8
9. env.XDOCLET_HOME=${env.ADEMPIERE_SOURCE}/tools
10. env.ADEMPIERE_ENV=Y

In the above file,


• line 1 is set to your source directory where you have downloaded the SVN source.
• line 2 is set to your SVN source disk root for example C:\ D:\ or /usr etc
• line 3 is where adempiere install files are written to. In other words if this directory
does not exist, the build process will create it.
• line 4 is where your SVN Source is and build process will create an 'Installers' folder
under this directory. It is not necessary to have this line point to SVN source directory
instead it can be pointed to any other directory where you want your zipped up
version of installer files are to be created. These zipped version is equivalant to line 2
directory content.
• line 5 thru line 10 can be left at default values.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 133
After setting up the file you can run the script utils_dev/RUN_build (.bat for windows
or .sh for linux).
This process will create installer files in the env.ADEMPIERE_INSTALL configured
directory:
• Adempiere_Trunk.tar.gz – gzipped tar for linux installation
• Adempiere_Trunk.tar.gz.MD5 – md5 checksum for the gzipped tar file
• Adempiere_Trunk.zip – zipped file for windows installation
• Adempiere_Trunk.zip.MD5 – md5 checksum for the zipped file
You can use gzipped tar or zipped file in any environment – you just need to have the
needed decompressing tool. The script also decompress the file in the directory
configured as ADEMPIERE_HOME.

Exercise: Download trunk, a tagged version or a branch (copy from CD or server)


and build Adempiere installers

Server Installation
First you need to set up two environment variables: ADEMPIERE_HOME and
JAVA_HOME, i.e.:

SET ADEMPIERE_HOME=C:\Adempiere
SET JAVA_HOME=D:\Java\jdk1.5.0_11

Once the prerequisites are installed and tested the installation is straightforward:
1. Uncompress Adempiere
2. Setup the installation
C:\Adempiere\RUN_Setup (.bat or .sh) to setup the adempiere (application-)server.
C:\Adempiere\utils\RUN_ImportAdempiere (.bat or .sh) to import initial adempiere
data into your database (as specified in RUN_Setup).

Hint:If you're reinstalling and have a previous backup ExpDat.dmp you can use
RUN_DBRestore (bat or .sh) instead

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 134
If everything went right you can start the server:

RUN_Server2

The most important part of the installation is to fill properly the RUN_Setup
parameters.
RUN_Setup creates Adempiere.properties (server environment) and
AdempiereEnv.properties (Environment info) – these files must be secured, they contain
sensitive information.
Finally, please note the RUN_Server2 leaves a session box opened (command line box).
To avoid this you would need to install adempiere as service:
in windows using the provided tools for %ADEMPIERE_HOME%\utils\windows
in linux using the tools on $ADEMPIERE_HOME/utils/unix.
DB and application server can be installed in one single server. Optionally you can
install DB in one server, and application in other server.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 135
4.5 Persistence Object

Now that we have got the source out of the way in terms of how to get it and set it up,
we like to examine one important aspect that haunts or brought a lot of interesting
discussions around it - the PO or Persistence Object implementation in the source.

You can have an idea by locating PO.java within the source. Then look for classes that
extends PO by doing a search for ‘extends PO’.

Figure 4.4 Search Box in Eclipse

The above search will return about 710 classes most of them X_*.classes. Here we will
focus more on the X_*.classes because together with the M_*.classes is what constitutes
the PO stack or the model’s data calling within the source. This is been debated to be
replaced by a more higher and contemporary technology such as Hibernate or from the
Spring Framework or OfBiz but for now, it is good to grasp its innards and essence of
how Compiere and ADempiere is possessed by it. Later we will see the Query.class
model of abstracting out the unwieldy SQL scripts from the M_*.classes or model
classes. This may not be the ideal way but it can be a good compromise as there are tons

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 136
of SQLs and model functionalities that is too daunting to migrate to Hibernate that
easily.

The regime that ADempiere has inherited is exposed in the following sample, whenever
an entity wants to access a field value within the model.

public class MBankAccount extends X_C_BankAccount


{
...
setBankAccountType (BANKACCOUNTTYPE_Checking);
}

public class X_C_BankAccount extends PO


{
...
public void setBankAccountType (String BankAccountType)
{

set_Value (COLUMNNAME_BankAccountType, BankAccountType);


}
}

public abstract class PO


{
...
protected final boolean set_Value (String ColumnName, Object value)
{
int index = get_ColumnIndex(ColumnName);
...

public final int get_ColumnIndex (String columnName)


{
return p_info.getColumnIndex(columnName);
}

Figure 4.5 Model Call Java Stack

Everytime a model class wants to do something it will go through the above sequence
and build up a context stack within its java call, that so often draws criticism from
present day developers as too monolithic and overweight. But as explained, this can be
efficient in the ERP framework to handle countless model calls. What can be done next

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 137
is to provide more better abstraction or refactoring within the model classes. One such
refactoring will be shown in a subesequent topic.

To understand further on what the stack is finally refering to in the abstract PO, as you
can see above, there is reference to ColumnIndex and columnName as well as p_Info
(POInfo.class). These are accessing the Application Dictionary (AD) domain where the
model is defined by information stored in AD_Tables and AD_Fields. Some lessons on
the AD was done in the ERP Setup module. Later we will provide a technical exposition
adapted from Carlos Ruiz’s article in wikiversity.

What we have to appreciate in the Compiere context of handling model and DB access
is that it is wired to the AD from the ground up. Let us think about what happens when
ADempiere is launched. It first calls its AD framework that calls its metadata of what
Menu tree with what Windows and Tabs and Columns to appear in the client. It is
rather like Spring and having its client presentation taken care of dynamically. As it is,
the sourcecode arrangement has sufficient logical separation between the AD and the
business model. Just that since Compiere was first written in the late 1990s, it does not
possess the sophistication of later Java technologies such as Hibernate or other ORM
frameworks. As we can see now, this AD framework is good enough to work on and
improve on.

The way the X_*.classes are pre-generated rather than resolved dynamically may give it
some speed over a dynamic GenericPO approach. You can refer the
GenerateModel.class to see how it is done where the AD table model will have its field
metadata resolved as final setter and getter methods. This GenerateModel.class is
manually run once everytime when deployment from source is needed. But lately it has
been deprecated by dynamic implementation of the set/get calls! So we can say that the
AD is pretty much separated from the developer’s plate. You can now focus more on
business logic development rather than any boiler plate toilings.

There is a deeper raw expose of such technicals compiled by Mario Calderon, from El
Salvador, also an ex-SAP expert with 30 years in Germany after researching it up
directly from Victor Perez[7]. The following is adapted from my wiki article on
Application Dictionary at www.adempiere.com.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 138
4.6 Application Dictionary Overview
1. Basically the architecture or model of ADempiere is based on Compiere's Application Dictionary
or AD Engine. It resolves the Model-View-Logic model of modern software design.
2. AD's Model Layer takes care of all the entities such as the core database table & field structure, its
datatype, reference and validation rules.
3. AD's View Layer takes care of its presentation in both the Java and HTML clients without the
developer needing to code a single line of extra user interface code.
4. AD's Logic Layer is where all the business logic and auxilary activity happens.
5. The software is built from the ground up with inherent capabilities namely the MULTIs features
such as multi-language, multi-org, multi-currencies, and Log4Java debugging set, and powerful
Java Objects such as Environment & Context, Persistence, Web and Application Service.
6. Its CRM and Webstore components are custom-built and thus do not fully rely on the AD
particularly the AD Menu and AD Window.
7. The AD Framework is very important that it enforces discipline in the the software application to
separate its tasks into distinct layers and allow the developer to dive straight into business
functionality without distraction from the supporting infrastructure.

Figure 4.6 Application Dictionary resolves Model to View architecture

Figure 4.6 above gives a visual graph to illustrate the relationship between the
various AD entities and types behind the Menu engine.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 139
At the Model Layer
1. All Table and Field structure are defined in the AD Table & Column window.
2. Each field's properties such as datatype and reference are defined in the same window.
3. Such reference can call up any resident Database table to return any value defined.
4. A field can possess a validation rule is defined in the AD Validation window.
5. Such validation can inject JavaScript, Java code or SQL script into the application to filter the
returning value of a reference.
6. A field can update other fields on the window or the underlying database via core callouts. The
Java framework to introduce such callouts is simply by extending the CalloutEngine.java and
accessing the MTab to getValue or setValue.
7. Any changes to the model such as introducing a new table to the database is done via the AD
Table & Column window.
8. The AD Engine resolves the preparation of the table and field structure for the View level such as
displaying via the standard user interfaces or reporting formats.

At the View Layer


1. As the Model is taken care of, the View Layer shall present the Model to the UI be it the Java
Swing or HTML Clients..
2. All CRUD (create, read, update, delete) functions are automatically taken care and shall appear in
the client interfaces without any further changes or effort during definition of new model
changes.
3. The UI is aware of new records, mandatory fields and saving errors.
4. It allows powerful search functions and field preference setting according to the User ID.
5. The View Layer is handled by AD Menu, AD Window and AD Process & Report
6. They communicate with the earlier Model Layer efficiently.

At the Logic Layer


1. Alot of visible power of the ERP Application happens here beginning with auxilary and accesorry
functions such as User Login, Role Access and Workflow reactions.
2. In a way, the Logic Layer is further separated from this Accesory portion as its own Business
Logic area which the functional developer is most interested in.
3. The Accessory portion is isolated from all the others so that it can function without any bug
introduced into it from the other layers. The developers are left free to modify the Application
Dictionary as the business demands.
4. Logic that are not handled in the above layers are handled by Callouts and Model Classes under
the control of the ModelValidator.
5. Core business logic processes such as Aging Analysis, Convert Requisition to PO or Complete
Orders are handled by Java classes that are called by the AD Report & Process engine. Input
parameter selection are facilitated for easy configuration by the developer without much
supportive coding in the fully Object Oriented Java environment.
6. The ADempiere project has refined the logic portion of the application further by introducing:

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 140
a. Separation of extended logic from core logic
i. This is acheived by strictly extending the ModelValidator scheme to cover dynamic usage
instead of just static as inherited from Compiere.
ii. This is used in the Table and Column window where a 3rd tab for Table Script Validator
is allocated.
b. Introduction of JSR223 Scripting in Rule Engine.
i. A callout may now utilise different programming scripting such as Groovy, Python or
Ruby if compliable.
ii. This gives scalability of application design and also 'developer scalability' can improve
tremendously.

Conclusion
• ERP is complex and an ERP Software Application can be even more complex. The role of the AD is
very vital and ingenious in dealing away with as much complexity of the software components as
possible to leave the users a structured modular understanding of the application.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 141
4.7 Application Dictionary Technicals
Now we are going into a more technical description of the Application Dictionary by giving an
elaborate glossary of its terminology. This is adapted from Carlos Ruiz’s wikiversity article on the
same subject.

Entity Types
The entity type determines the ownership of Application Dictionary entries. The types "Dictionary"
and "Adempiere" should not be used as they are maintained by ADempiere – this is regarded as the
official ADempiere dictionary.
Last addition in Adempiere (3.3.1) is to define a model package to look for model classes based on
entity types (i.e. Look in org.eevolution.model instead of org.compiere.model)

Element
This is the central repository for field names, description and help/comments. As well as translations.
Define the names, label, description, help for sales and purchase contexts.
• Centralized terminology – if you need an exception disable “centrally maintained” in
field( windows Tabs & Field).

Table and Column


This is closely related to database, it is kind of metadata of the database tables and columns translated
to Adempiere “object” notation.

Tables
• Case sensitive
• If the table has an ID it must be exact case with the table name (i.e. CUST_MyTable – the column id
must be named exactly CUST_MyTable_ID)
• View – to define the table definition as view, views are not synchronized in database. You can use it
also to make a table read-only
• Data Access Level – Used for defining the default access for roles
• Maintain Change Log – when selected all changes to this table are logged in AD_ChangeLog table –
it doesn't matter if the role is logged or not
• Window – define the window to enable zoom functionality. Also you can define a different zoom
window for purchase process (PO Window).
• Records deleteable – to allow/disable deletion of records in database
• High Volume - indicates if a search screen will display as opposed to a pick list for selecting records
from this table.
• Create Columns from DB: If you make changes in database (ALTER TABLE ADD/MODIFY
columns) – you can get the changes with this process.
• Copy Columns From Table: This is the quickest process to create a table – you select a similar table
and this process will create all columns with exact columns (the ID will be renamed to match the

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 142
table name) – then you can edit (add/delete/change) the columns and when you finish just push
the button Synchronize Column to create the table in database.

Columns
• System Element – the DB Column Name, Name, Description and translation will be inherited from
the element at saving time
• DB Column Name – the exact name of the column in the database
• Column SQL – for virtual columns. Virtual columns can show summary information, or
information from other tables without the need of adding a real column to the database. Is
constructed with a select joined with the main table.
• Reference: Data Type of the column- each reference correspond to a different behavior in GUI.
Please note carefully the difference between Table and Table Direct. Table Direct needs exact match
of the case for the table with the name of the column (excepting the suffix _ID)
• Please note also the difference between Table and Search
• For buttons you can define an associated process
• For Amount, Date, Integer, Number, Quantity you can define a range of min and max value
• Validation: Dynamic change for list and searches
• Reference Key: Static list for tables and lists
• Value Format: For strings you can define a format for the field. Adempiere formatting can enforce
the usage of space, any letter, uppercase, lowercase, letters & digits, only digits, etc. I.e. Formatting
phone numbers
• Default Logic: Context variables – SQL Statements. You can define several defaults separated by “;”
- the first one not-null will be the default
• Key Column: Just one per table (Primary Key – normally ID generated internally, not shown for
users)
• Parent Link Column – Define the child relation with one or more tables – there can be tables
without ID but with one or more parents (like Access tables)
• Mandatory
• Updateable
• Always updateable – make this field always updateable, even if is processed
• Encryption: just for strings – no reversal process – you can loose data, you need to ensure the width
of the column can hold all the current values.
• Read only logic – condition for making the record read-only (by default IsActive and Processed
columns mark the record as readonly without the need of defining the logic here)
• Mandatory logic – condition for making this field mandatory
• Identifier: one or more columns (normally value and/or name) to be shown in lists and for
dereferencing in reports. The identifiers are shown in the order defined in the field Sequence
• Callout – piece of code (customization) for filling other fields or simple validations (not
recommended for validations – you still need to validate on saving) – for string fields callout is
called in keystroke basis
• Selection column – define the column(s) to be shown in the default search window – by default
Value and Name columns are searchable
Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering
P a g e 143
• Translated – to define translations for a column – in this case you need to define a table and a tab
with the same name as the original table and the suffix (_Trl), and create the table with the same
key as the parent, language column and the translated columns

Reference
The Reference Window defines field/display types and validations.
Supported Data Types:
Type Description
Account Account Element
Amount Number with 4 decimals
Assignment Resource Assignment
Binary Binary Data
Button Command Button - starts a process
Color Color element
Costs+Prices Costs + Prices (minimum currency precision, but if exists more)
Date Date mm/dd/yyyy
Date+Time Date with time
FileName Local File
FilePath Local File Path
ID 10 Digit Identifier
Image Binary Image Data
Integer 10 Digit numeric
List Reference List
Location (Address) Location/Address
Locator (WH) Warehouse Locator Data type
Memo Large Text Editor - Character String up to 2000 characters
Number Float Number
Printer Name
Product Attribute Product Attribute
Quantity Quantity data type
RowID Row ID Data Type
Search Search List
String Character String
Table Table List (Use Key and Display)
Table Direct Direct Table Access

NOTE: Table name is taken from the column name except the _ID suffix – CASE SENSITIVE (Use Key
and Identifier)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 144
Text Character String up to 2000 characters
Text Long Text (Long) - Text > 2000 characters
Time Time
URL URL
Yes-No CheckBox:

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 145
4.8 Query Refactoring

As promised earlier, I will give some treatment on the effort done by a few of our core
committers such as Teo Sarca (Romania) and Victor Perez (Mexico) to remove SQL
queries from model classes and replace them with refactored query statements. First, we
take a peek at the big picture by showing what is before and after when using the new
query. Below is a diff patch to give a line by line change description:

+ * FR: [ 2214883 ] Remove SQL code and Replace for Query - red1
*/
public MCommissionLine[] getLines()
{
//[ 1867477 ]
- String sql = "SELECT * FROM C_CommissionLine WHERE IsActive='Y' AND C_Commission_ID=?
ORDER BY Line";
- ArrayList<MCommissionLine> list = new ArrayList<MCommissionLine>();
- PreparedStatement pstmt = null;
- try
- {
- pstmt = DB.prepareStatement(sql, get_TrxName());
- pstmt.setInt(1, getC_Commission_ID());
- ResultSet rs = pstmt.executeQuery();
- while (rs.next())
- list.add(new MCommissionLine(getCtx(), rs, get_TrxName()));
- rs.close();
- pstmt.close();
- pstmt = null;
- }
- catch (Exception e)
- {
- log.log(Level.SEVERE, sql, e);
- }
- try
- {
- if (pstmt != null)
- pstmt.close();
- pstmt = null;
- }
- catch (Exception e)
- {
- pstmt = null;
- }
-
+ //FR: [ 2214883 ] Remove SQL code and Replace for Query - red1
+ String whereClause = "IsActive='Y' AND C_Commission_ID=?";
+ List<MCommissionLine> list = new Query(getCtx(), MCommissionLine.Table_Name, whereClause,
get_TrxName())
+ .setParameters(new Object[]{getC_Commission_ID()})
+ .list();
// Convert
MCommissionLine[] retValue = new MCommissionLine[list.size()];
list.toArray(retValue);

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 146
As you can see from the above source diff, about 25 lines are replaced by 5 lines of code.
Not just the reduction in codes, but now its cleaner as no more SQL strings are needed
in such model classes. All SQL string formats are refactored to the Query object. This
will allow more SQL standards control enroute to database independence. As some
databases may implement model queries differently, the query implementation of SQL
statements can be switched at runtime in its relevant layer and in one area rather than
all over the place at the application code layer.

This refactoring separates the DB access handling from the business logic which is clear
from the above example. Model statements will then be cleaner and more readable as
well as easier to debug and isolate according to type of errors.

BEFORE Model Logic SQLs DB Access

AFTER Model Logic SQLs DB Access

Figure 4.7 Query refactoring separates the Model from the Data layer

There are probably many hundreds of such cases all over the application. You can find
that out by doing a search for a sample SQL statement or DB behaviour such as
“DB.prepareStatement” to sniff out their existence. Their replacement in the project
trunk is now underway but due to its high occurence they are done carefully and with
JUnit testings to ensure no mistake or bug creep into the new query replacements.

Once a complete replacement is achieved, the sourcecode will have taken one giant step
forward towards better maintenance and portability. Below we display the new Query
implementation of the above example. You can see that the SQL call is refactored here
under the BuildSQL method.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 147
Query.class
public <T extends PO> List<T> list() throws DBException
{
List<T> list = new ArrayList<T>();
String sql = buildSQL(null, true);

PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement (sql, trxName);
rs = createResultSet(pstmt);
while (rs.next ())
{
T po = (T)table.getPO(rs, trxName);
list.add(po);
}
}
...

private final String buildSQL(StringBuffer selectClause, boolean useOrderByClause)


{
if (selectClause == null)
{
POInfo info = POInfo.getPOInfo(this.ctx, table.getAD_Table_ID(), trxName);
if (info == null)
{
throw new IllegalStateException("No POInfo found for
AD_Table_ID="+table.getAD_Table_ID());
}
selectClause = info.buildSelect();
}

StringBuffer whereBuffer = new StringBuffer();
if (!Util.isEmpty(this.whereClause, true))
{
if (whereBuffer.length() > 0)
whereBuffer.append(" AND ");
whereBuffer.append("(").append(this.whereClause).append(")");
}
if (this.onlyActiveRecords)
{
if (whereBuffer.length() > 0)
whereBuffer.append(" AND ");
whereBuffer.append("IsActive=?");
}
if (this.onlyClient_ID) //red1
{
if (whereBuffer.length() > 0)
whereBuffer.append(" AND ");
whereBuffer.append("AD_Client_ID=?");
}
if (this.onlySelection_ID > 0)
{
String[] keys = table.getKeyColumns();
if (keys.length != 1)
{

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 148
throw new DBException("Table "+table+" has 0 or more than 1 key
columns");
}
//
if (whereBuffer.length() > 0)
whereBuffer.append(" AND ");
whereBuffer.append(" EXISTS (SELECT 1 FROM T_Selection s WHERE
s.AD_PInstance_ID=?"
+" AND s.T_Selection_ID="+table.getTableName()+"."+keys[0]+")");
}

StringBuffer sqlBuffer = new StringBuffer(selectClause);
if (whereBuffer.length() > 0)
{
sqlBuffer.append(" WHERE ").append(whereBuffer);
}
if (useOrderByClause && !Util.isEmpty(orderBy, true))
{
sqlBuffer.append(" ORDER BY ").append(orderBy);
}
String sql = sqlBuffer.toString();
if (applyAccessFilter)
{
MRole role = MRole.getDefault(this.ctx, false);
sql = role.addAccessSQL(sql, table.getTableName(), true, false);
}
if (CLogMgt.isLevelFinest()) log.finest("TableName = "+table.getTableName()+"...
SQL = " +sql); //red1 - to assist in debugging SQL
return sql;
}
...

You can see at the last line above, I have done my very small part in making the code
more debuggable by intoducing a logger prompt to display the table and its fully
qualified SQL statement. This line will only be seen when the debug logger is set to
finest in the Preferences Window.

You can learn up all the new Query implementation methods for all SQL cases such as
FirstOnly(), First(), and setParameters() by looking through http://
www.adempiere.com/index.php/ADempiere_Best_Practices and going to the sub-topic
#How_to_use_Adempiere_Query_class.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 149
Summary
1. Java is an industry standard accepted by most software institutions and has matured
with alot of APIs and benchmarkings and certifications on various industries.

2. ADempiere as inherited from Compiere is on Java and uses certain common patterns.

3. ADempiere project sourcecode is always open and available for checkout into a local
IDE such as Eclipse.

4. Much of the know-how is published in the www.adempiere.com wiki or online blogs


belonging to individual contributors.

5. The Persistence Object is extended by the X_classes which in turn are extended by the
Model classes that handle higher level model and business logic.

6. Query class helps to refactor away SQL scripting from the model classes into a single
place within it.

7. The Application Dictionary allows versatile configuration of the application model


and structure by a layperson without knowing about the sourcecode.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 150
Quiz
1. Which progamming language do you know well and why is it enough for you?

2. What are the recent and upcoming improvements expected on Java?

3. What does the Query class implementation improve upon?

Glossary

Term Description

Benchmark An analysis to test the performance of something against


something more common

Trunk The main location where sourcecode is kept and updated to

Branch Separately maintained part of the trunk where development or


testing is done for easier management.

Business The ability to analyse data and present in high level but statistical
Intelligence formats usually done with software tools.

SourceForge.net The most popular and largest repository for Open Source projects
to house and operate from.

Object To ensure that an object or value is stored and retrievable on


Persistence demand by the program

Refactoring An act to reduce excess codings by grouping same parts into a


common reusable component or methods.

Application Configuration framework to determine the application behaviour


Dictionary up to specific details such as menu and model structure

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 151
References
1. http://littletutorials.com/2008/05/28/13-reasons-java-die-old-age/

2. http://stackoverflow.com/questions/631003/microsoft-vs-java-career

3. http://www.jelovic.com/articles/java_good_bad.htm
4. http://www.idiom.com/~zilla/Computer/javaCbenchmark.html

5. http://discuss.joelonsoftware.com/default.asp?joel.3.312232.47

6. http://www.ohloh.net/p/adempiere/analyses/latest

7. h t t p : / / d o w n l o a d s . s o u rc e f o rg e . n e t / a d e m p i e re / D e v e l o p e r G u i d e . p d f ?
use_mirror=osdn

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 152
Chapter 5 - Modifying ERP

Learning Objectives
By the end of this chapter, the student shall be able to:

1. List the ways to modify the ERP application;

2. Create different module packages and different distributions;

3. Use meta-data coding without impacting sourcecode;

4. Extending core with ModelValidator.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 153
Introduction
Touching code is the first thing anyone would want to do and it is the hardest. Once
you get beyond that, you will come to the code changing part. That is also very hard.
You will need some survival Java and database know-how particularly SQL.

Software programming is still an archaic activity, not unlike a row of ladies in a loom
factory stitching a large piece of garment with their bare hands albeit skillful fingers. A
Java developer today still combs through lines of codes, albeit with a great visual tool
such as Eclipse or Netbeans. It is for all intents and purposes a highly manual vocation.
In fact, the garment industry has progressed to full automation where manual labour is
almost gone, but the software industry still need human eyes and brains to literally do it
in manual stitches. No machine can do the work of a software developer as a robotic
Toyota factory can in making cars.

The ADempiere project has brought together some of the marvelous brains from around
the globe in trying out some ideas of resolving the software crisis in ERP application
making. Many of the ideas are grounded on one single concern - to cater to a worldwide
audience, and so not to make the application core specific to any particular locale or
country but alienating another general or specific usage. We learnt how to modify core
without touching it, such as using the ModelValidator to extend it, or 2Pack to house
package metadata instead of binary code patches. We learn also the best way to make
releases without getting creeping bugs. We are using the most open powerful test
engines such as Fitnesse and Hudson. We also looked at good ways to distribute the
application ranging from branch distros to virtual machines.

Perhaps the most important contribution from the ERP software community built
around this project is the tons of documentation in wiki and other formats such as flash
movies, demos and individual blogs. Previously it was a mystical science to think about
learning ERP application development. Today it is a matter of googling for it online.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 154
5.1 Extending ADempiere
The great thing about Open Source is the ability or freedom to extend it to cover the
functionality that is peculiar to your industry or discipline. Here we will go through
what is commonly used by the top developers and committers around ADempiere.
Hopefully you will become more familiar as time goes by. The terminologies are rather
new and tedious, so I will do my best in providing associative concepts and visuals to
glue them together in a single learning curve. The next topic is derived from my own
wiki pages as well as guided by Carlos Ruiz’s wikiversity article ‘Extending
ADempiere’[1].

Extension Tools

ADempiere can be extended with the following tools or approaches:


* Callouts
* Customization.jar
* Model Validator
* Java Triggers
* Processes
* Views and Reports
* Forms
* Print Formats
* Import File Loader
* Log Migration Script
* 2Pack

We shall go through them in detail. But first, we divide the above into two broad
categories:
1. Micro tools
a. Callouts
b. Customization.jar
c. Model Validators
d. Java Triggers

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 155
2. Macro tools
a. Processes
b. Views and Reports
c. Forms
d. Print Formats
e. Import File Loader
f. Log Migration Script
g. 2Pack

Import File Loader is more of a migration tool, to bring in model data from a legacy or
3rd party system. There are 2 advanced tools created by the community, the Migration
Log mechanism and the 2Pack that basically record changes done in one ADempiere
instance for transfer to another more effortlessly. Though they are not strictly tools used
for extending, they are important in the maintenance of any extension work.
2Pack and Log Migration Script mostly concern changes in the Application Dictionary.
In the AD is where most configuration changes to the application occurs. You must have
noted in previous modules or lessons that changing ADempiere requires two areas of
focus: Change in code and change in the AD. As the AD is just meta-data, their change
will result in SQL or XML scripts. The former is when you are using Log Migration
Script and the later is when you are using 2Pack. More about these tools later.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 156
5.2 Callouts
This is one of the most ingenious tool introduced by Jorg Janke in the Compiere ERP
software that we inherited from. Basically the Callout works from any field column in a
table as displayed in a window. The Callout allows that field to derive information more
dynamically and from any other source rather than just its direct database reference.

DB Field

EXTENDING
> other columns
> other fields
Callout > other Tabs
> other Tables
> other Windows
> apply logic

Figure 5.1 Callout changes column value dynamically

How It Works
A Callout is a java method which gets executed when the field in an ADempiere window tab
gets focus and onChange activity. A Callout class (extending CalloutEngine) will group such
methods into a single file, usually under a document name i.e. CalloutOrder.java. A Callout is
defined in the Table & Column window, under a column tab, where you may specify a list of
fully qualified methods (separated by ";"). Below we shall create a test case and place it in a
customization jar just to learn another point in our development, which is not touching your
present main sourcecode too much.

Steps to create a callout


To write a callout you have to do the following things:

1. Write the callout function


package org.adempiere.callout;
import java.util.Properties;
import org.compiere.model.CalloutEngine;
import org.compiere.model.GridField;

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 157
import org.compiere.model.GridTab;
import org.compiere.util.AdempiereSystemError;
import org.compiere.util.Env;

public class SimpleCallout extends CalloutEngine {


public String test(Properties ctx, int windowNo, GridTab mTab, GridField mField,
Object value) throws AdempiereSystemError {

log.fine("test callout");
log.fine("tab name: " + mTab.getName());
log.fine("window no: " + windowNo);
log.fine("window name: " + Env.getWindow(windowNo).getName());

return "this is a return string";


}
}

The full qualified name of the method is org.adempiere.callout.SimpleCallout.test - you


will need this in the next step.
2. Login as system administrator and open the 'Table & Column' window. Choose your table
and navigate to the Column tab, place your cursor in the Callout field, and enter the fully
qualified method name.

Figure 5.2 Samples Callouts in OrderLine Table/Column

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 158
3. Create a jar file with your callout classes and rename it to customization.jar. Copy this
customization.jar into the Adempiere/lib folder of your ADempiere installation and rerun the
RUN_setup.bat/sh. Restart the ADempiere server and install the new client (or restart the
client with Java WebStart).
4. Test your callout by navigating to the field where you added the callout and change it's value.
If you used the test callout you should see it's output in the console (if your trace level is set
to fine or a higher level). You can change the trace level in Tools -> Preference -> Trace Level.

Tips
You can have callout functions with 5 parameters (like in the example above) or 6 parameters.
The last parameter is the old value.

public String callout (Properties ctx, String method, int WindowNo,


GridTab mTab, GridField mField, Object value, Object oldValue);

I have made a listing of all the Callouts in ADempiere for easy online reference. You can click on
each Callout in the table to lead to the actual Callout coding. (http://www.adempiere.com/
index.php/Callout_Code)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 159
5.3 Callouts (Meta-data)
There is a new contributed addition to ADempiere’s Callout mechanism, which is to
issue Callouts without touching sourcecode! This is done by JSR 223 Scripting interface
that allows a Callout Script to be defined in text format and it is then injected at
runtime. Such scripts are defined in the Rule Window which also allow other event
tools besides Callout. contributed by Carlos Ruiz with improvements by Victor Perez.

Creating the Rule


Within the script you can use:
• Window context variables start with a W_ prefix
• Login context variables start with G_ prefix
• Parameters for callout start with A_ prefix
• A_WindowNo
• A_Tab
• A_Field
• A_Value
• A_OldValue
• A_Ctx

Figure 5.3 Rule window defining Callout Script

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 160
Configure Callout from Table/Column
We still need to configure the Table/Column window to refer to the Callout via the Rule
mechanism.

Figure 5.4 Defining Callout as a Beanshell Rule Script

• This Callout can also be called from the Report & Process Window. Just remember to set in the
Rule window from which Event Type are you calling this Rule Script.

Sample Code provided for copy/paste testing


On the Table and Column, callout reference:
@script:beanshell:BP_fillDescriptionFromName
On the Rule Search Key:
beanshell:BP_fillDescriptionFromName

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 161
On the Rule Script:
if (A_Tab.getValue("Name") != null) {
A_Tab.setValue("Description", A_Tab.getValue("Name"));
}
result = "";

Scripting Languages
1. Now standard Adempiere has uploaded jars to work with groovy, jython and beanshell
2. to call a script from a Callout follow these sample syntax:
a. @script:beanshell:ValidateQtyOnHand
b. @script:groovy:ValidateQtyOnHand
c. @script:jython:ValidateQtyOnHand
3. When you create the rule, you have to set in the Search Key such as:
4. Search Key : beanshell:ValidateQtyOnHand
5. Search Key : groovy:ValidateQtyOnHand
a. Search Key : jython:ValidateQtyOnHand
6. Set the Event Type as Callout and Rule Type as JSR 223 Scripting APIs

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 162
5.4 Rule Script for Process
You can use the above Rule scripting for the Report & Process window in defining its
core process steps or business logic to execute.
Within the script you can use:
• Login context variables start with G_ prefix
• Process Parameters for the process start with P_ prefix, for example P_Name
• If the parameter is a range then the parameters will be P_Name1 and P_Name2
And the following predefined arguments:
• A_Ctx - the context
• A_Trx - the transaction
• A_TrxName
• A_Record_ID
• A_AD_Client_ID
• A_AD_User_ID
• A_AD_PInstance_ID
• A_Table_ID

Figure 5.5 Rule Scripting for Process

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 163
Configure the Process

Figure 5.6 Setting Rule in Process Window

Code provided for copy/paste testing


On the Report & Process:
@script:beanshell:ImportDelete
On the Rule Search Key:
beanshell:ImportDelete
On the Rule Script:
import org.compiere.model.MTable;
import org.compiere.util.DB;
import org.compiere.util.Msg;

/* get Table Info */


MTable table = new MTable (A_Ctx, P_AD_Table_ID, A_TrxName);
if (table.get_ID() == 0)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 164
throw new IllegalArgumentException ("No AD_Table_ID=" + P_AD_Table_ID);
String tableName = table.getTableName();
if (!tableName.startsWith("I"))
throw new IllegalArgumentException ("Not an import table = " + tableName);

/* Delete */
String sql = "DELETE FROM " + tableName + " WHERE AD_Client_ID=" +
A_AD_Client_ID;
int no = DB.executeUpdate(sql, A_TrxName);
A_ProcessInfo.addLog (0, null, null, "Deleted "+no+" rows from table "+tableName);
result = "OK";

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 165
5.5 Customization.jar
When you need to modify or override some functionality in core classes, the wise way
is to leave the core classes alone and create a new copy of the class and place it in a
special place called customization.jar. This is a practice in Java programming known as
‘overloading the java class’.

Project Customization Management Hints


The recommended set up for projects is:
• create one-big eclipse project with last stable version (or the version you're implementing)
• create one eclipse project with the patches project for that version (if exists)
• create one eclipse project with the customized classes for your project
i.e.
• adempiere320 - from https://adempiere.svn.sourceforge.net/svnroot/adempiere/tags/
adempiere320
• patches_321 - from https://adempiere.svn.sourceforge.net/svnroot/adempiere/branches/
patches_321
• your_project - from your own svn or cvs repository
You must not change adempiere320 classes - they are the tagged version.
You must not change patches_321 classes - they are officially released from Adempiere
community - unless you're a committer of adempiere project fixing problems with the version
You can create/change your project classes following the suggested guidelines below.

Customizing core classes


If you need to customize a core class in a particular version, you can just copy the java file from,
say adempiere320 or patches_321 into the custom project with the same directory structure.
For example, if you need to customize CalloutPayment.java, you must copy it from
adempiere320 to the trunk of the custom project in the folder base/src/org/compiere/model

IMPORTANT: Please take account if your change is fixing a bug, or a contribution worthy to be
integrated in trunk (or patches_321), if this is the case please refer to Adempiere forums in
sourceforge to discuss the specific case for nomination and acceptance via favourable voting.

Extensions and new classes


If you need to create new classes or extensions, please create them in the extend directory of the
custom project, i.e. extend/src/org/compiere/process/MyInvoiceGenerate.java

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 166
Generation of patches.jar and customization.jar
Following the previous guidelines for project management you can generate the
customization.jar file with the classes on bin subdirectory (or the selected build subdirectory in
eclipse) on your custom project.
You can also generate the patches.jar (or download it from file releases on adempiere
sourceforge) with the classes on bin subdirectory (or the selected build subdirectory in eclipse)
on patches_321 project.
Following this approach you won't have dependencies problems with RUN_build - as you don't
run RUN_build when releasing customization.jar and patches.jar - but you still need to run
RUN_setup specially if you're using webstart clients, or adding packages.

IMPORTANT NOTE: The precedence on ADempiere is:


1. customization.jar
2. patches.jar (official patches_321)
3. Adempiere.jar (official)

With this precedence you must take account that you can have problems if your project has a
customized class that is released in the patches project - you must review and apply the changes
to your customized class.
Also note that the content of patches.jar and customization.jar is inserted into Adempiere.jar.
Therefore, if playing around with different versions on your own patches.jar, be aware that
classes you altered with the patch are not automatically changed back to normal after you
installed a new patch without the changed class files.

Running ADempiere from within Eclipse


Connecting to multiple adempiere instances:
VM Arguments
-DPropertyFile=C:\Users\Carlos\AdempiereTrunk.properties

You can also use arguments to extend the memory assigned for Adempiere, i.e.:
-Xms32m -Xmx512m

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 167
Debugging ADempiere
Debugging Server
(This description uses Adempiere 3.4.2)
To debug the server you have two possibillities:
a. Shared Memory Debugging - means debugging "on site" i.e. you'll have to work at the server
or
b. Remote Socket Debugging - this option will be described here because very often you'll have
a production system and a second one for R&D or when working at a Windows system.

Attention: DO NOT USE DEBUGGING ON A PRODUCTION SYSTEM - unless you know


exactly what you are doing! Debugging can stop all server processes of the adempiere service
until you resume it. Recommendation is to user either a testing system or a separately setup
copy of the production system.

Settings at the Server


Central point is the JBOSS service with it's settings at the file [Adempiere Home]/jboss/bin/
run.cfg and it's last two option lines:

# Sample JPDA settings for remote socket debuging


#JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport = dt_socket,address
= 8787, server = y,suspend = y"

# Sample JPDA settings for shared memory debugging


#JAVA_OPTS="$JAVA_OPTS -Xdebug -Xnoagent -Djava.compiler=NONE -
Xrunjdwp:transport=dt_shmem,server=y,suspend=n,address=jboss"

With uncommenting one of these lines you'll enable the debugging. The lower (or last) line here
is the option for shared memory debugging which you can use for debugging at the server
itself. The upper line have to be uncommented for external debugging means via network
connection. As you can see the transport type is set to socket and what is named "address" is the
port to be used on this machine.
Be aware that if your server has a firewall installed (should have be so!!!) you'll have to open
this particular port for using it!!
But you can use any other port too - as long as it's not beeing used by another service or
program.
After successfull changing one of these lines you'll have to restart the adempiere process. For
debugging it's recommended to use [Adempiere Home]/utils/RUN_Server2.sh (or .BAT) in
"normal" mode (without sending it to backgroud by " &") so you have better control about

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 168
output. After starting the service it will immediate stop with the line "Listening for transport …"
which means that it's waiting for a debugging session to connect.
Now it's time for the remote part.

Settings at ECLIPSE (remote part)


First of all you'll have to open the source code that you like to have debugged and set your
break points there. After that you'll be raedy for starting the debugging session. Go to "Run" ->
"Debug Configurations..." - where you can find the configuration entry "Remote Java
Application". Mark it and click onto "New lauch configuration" and give it a name. Normally
the "Connect"-Tab used standard values like the actually opened project. Change the values as
requiered, the "Connection Type" is "Standard" which means the socket connection to the
debugging service. Host and port have to be set to IP address or qualified (resolvable) name of
the machine to be debugged and the port number is the one you have set above.
Start debugging with the button "Debug".
You will see that you have two buttons active: "Suspend" and "Disconnect" at the debugging
perspective.

Debugging session
The first thing you can examine is that the stopped session at the server now start and go ahead
to normal operation, last entry is the startup time. At this point you can connect to Adempiere
with a normal client - or to make it difficult using another debugging session with a client from
another desktop session or computer. You can go ahead with normal operations or testing your
applications up to the point where your break points become effective. A typical example for
server operation is the posting of a delivery note or an invoice.
When the debugger stops it will show contents of source code with the maker set to the
corresponding line. Now you can examine the value of variables and resume operations step by
step (F5), line by line (F6) or go ahead to next break point or resume operations (F8).

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 169
5.6 Model Validator
A model validator is java class that implements org.compiere.model.ModelValidator. It
has two important (callback)methods (modelChange and docValidate) which are called
on model change events and document events. The model validator register itself for
certain ADempiere tables or documents to react on model changes (data changed,
added or deleted) or document actions like complete, void etc.

Model change events


Model Change events occur every time when data of an ADempiere db table is changed. There
are events for data insertion (TYPE_BEFORE_NEW/TYPE_AFTER_NEW), change of data
(TYPE_BEFORE_CHANGE/TYPE_AFTER_CHANGE) and deletion (TYPE_BEFORE_DELETE/
TYPE_AFTER_DELETE).

Document events
Document events occur on the change of the document status. So you have
BEFORE/AFTER CLOSE/REACTIVATE/ REVERSECORRECT/ REVERSEACCRUAL/
COMPLETE/PREPARE/ VOID/ POST

Login Event
It's called when a user log into Adempiere - you can log or restrict users to log in according to
business rules.

FactsValidate Event
It's called when posting a document (accounting). You can change the facts being posted
(similar to calling BEFORE_POST document event.

LoadPreferences Event
It's called after the adempiere preferences are loaded - useful to add context variables or things
after log in.

SaveProperties Event
It's called when a user is saving properties - useful to restrict changes on properties file (Tools ->
Preferences).

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 170
Steps to create and register a model validator
1. Create your own validator class which implements the interface
org.compiere.model.ModelValidator.

* Register the table/document in the initialize() method.

/**
* Get Client to be monitored
* @return AD_Client_ID client
*/
public int getAD_Client_ID()
{
return m_AD_Client_ID;
} // getAD_Client_ID

public void initialize (ModelValidationEngine engine, MClient client)


{
// This line must come before registering the model changes
//client = null for global validator
if (client != null) {
m_AD_Client_ID = client.getAD_Client_ID();
}
[...]
// register for model change on C_Order
engine.addModelChange(MOrder.Table_Name, this);
// register for document events on MOrder
engine.addDocValidate(MOrder.Table_Name, this);
} // initialize

• Put your code into modelChange() for model change events and into docValidate() for
document events.
• You have to check the parameters po for the table name (po.get_TableName() - if you
registered more than one table/document) and timing/type to react on the right
events.

public String modelChange (PO po, int type) throws Exception


{
// we want to validate the order before the deletion

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 171
if (po.get_TableName().equals("C_Order") && type == TYPE_BEFORE_DELETE)
{
MOrder order = (MOrder)po;
// put your code here
}
return null;
} // modelChange

public String docValidate (PO po, int timing)


{
if (timing == TIMING_BEFORE_COMPLETE) {
if (po.get_TableName().equals(MOrder.Table_Name))
{
//put your code here
//it is executed every time an order is about to complete
}
}
return null;
} // docValidate

2. Register your validator in ADempiere. Login as System Administrator and open the
'Client' window. Here you have to enter you validator class (full qualified name) into
the ModelValidationClasses field.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 172
Figure 5.6 Client Window for setting ModelValidator

3. Create a jar file with your validator class and rename it to customization.jar. Copy this
customization.jar into the Adempiere/lib folder of your ADempiere installation and
rerun the RUN_setup.bat/sh. Restart the ADempiere server and install the new client
(or restart the client with Java WebStart).

5.7 2Pack
2Pack is the creation of Robert Klein[2] based on the XML2AD work of Marco Lombardo
in which was also improved by Trifon Trifonov with his AD2XML. Carlos Ruiz and
Trifon then housed the improvements in a separate project ComXe. During pre-2Pack
days, I have written about its progress in the XML2AD Tutorial.

2Pack is now migrated into ADempiere. Carlos Ruiz has finished that as to the latest
version and it has been used by several individuals to do Colombian and German

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 173
Accounting Localisation and Libero Manufacturing packages. To date Tim (xp-prg) has
studied it deep enough to the extent of maintaining it and extending it to cover the
WorkFlow aspects as needed by Libero.

Some Future

I was trying to look at using 2Pack for replication purposes between ADempiere
instances. Initial challenge is to overcome Foreign Key IDs and Unique ID constraints in
Search Value fields. Below I relate my attempt so that newbies can follow a glimpse of
2Pack engineering. The good news is that someone better like Low Heng Sin has better
ideas on resolving it but it is not shown here. You have to search it in the tracker logs.

Some Present

I was proposing an approach to resolve the Foreign Key issue during runtime by
transposing the SearchKeyValue with the given FK_ID. During PackOut we implement
a ReturnValueFromID to store the SearchKeyValue instead of the FK_ID which is not
guaranteed in target Database. During PackIn we implement a ReturnIDFromValue to
replace the SearchKeyValue with the resident FK_ID in the target Database.

This is assuming that the SearchKeyValue is unique. However a failure of this will not
be fatal. Just some inaccuracy in data that can be easily checked after migration of the
tables.

The FK table has to be present first in the target DB. If new records then they have to
migrated over also. This approach is now not sound as not all data tables have
SearchValue fields.

Carlos Ruiz has replied to me in the wiki talk page that he has solved it for PackIn. Its
merely PackOut that needs to create the ValueFromID 'lookupname'. We can try
implement only in tables that have the Value field.

Foreign Key Issue

One way is as shown by Carlos Ruiz where FK IDs are replaced with LookUpNames.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 174
I have contributed a patch in SourceForge tracker and it was tested ok for 1 Order
record containing an Order header with its OrderLine. Here I link the XMLs to show
how the patch work >BEFORE and AFTER. You can click on both of them and switch
between each other in your browser to see where the lookupNames replace the Foreign
Keys in both tables.

Figure 5.7 PackOut.xml before using Lookup

(cont’d next page)

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 175
Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering
P a g e 176
Figure 5.7 PackOut.xml after using Lookup

(cont’d next page)

* Note that here we even do lookup for SalesRep and C_Order_ID as DocumentNo.

* The test done is basically the transfer of a single Sales Order from one instance to
another instance that has already an extra SO so to prove that the difference in IDs
doesn't break the FK relations integrity.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 177
Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering
P a g e 178
5.8 2Pack Any Table
Example provided by Carlos. [3]

34 <data clientname="GardenWorld">
35 <dtable name="C_Tax">
36 <drow key1name="" lookupkey1name="" name="ICA 4,14 * 1000" key2name=""
lookupkey2name="">
37 <dcolumn name="AD_Org_ID" class="Table Direct" value="0"/>
38 <dcolumn name="IsActive" class="Yes-No" value="Y"/>
39 <dcolumn name="Name" class="String" value="ICA 4,14 * 1000"/>
40 <dcolumn name="Description" class="String" value="null"/>
41 <dcolumn name="Parent_Tax_ID" class="Table" value="null"/>
42 <dcolumn name="C_Country_ID" class="Table" value="156"/>
43 <dcolumn name="C_Region_ID" class="Table" value="null"/>
44 <dcolumn name="To_Country_ID" class="Table" value="156"/>
45 <dcolumn name="To_Region_ID" class="Table" value="null"/>
46 </drow>
47 </dtable>
48 </data>

This is like the previous example I pasted above where the LookUpKey1Name values are implemented.
This is the resolve the FK issue which are local serial unique integers that may conflict as different
instances are merged.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 179
5.9 Example of exporting Payment Terms with 2Pack
This is am example contributed by Matjaž Godec of Slovenia.
Before you can export as clientAdmin You have to make PackOut accesible to Admin user like Bojana
explained here: https://sourceforge.net/forum/message.php?msg_id=4791865

Figure 5.8 Select PackOut from Menu

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 180
Figure 5.9 Select PackOut from Menu

Creation directory is path to the disk space You want package to be exported to.
Select Tab "Package Details" and fill required fields as on picture:

Figure 5.10 SQL script to filter Payment Term Data


SQL: SELECT isactive,name,description,documentnote, afterdelivery,isduefixed, netdays,gracedays,
fixmonthcutoff, fixmonthday,fixmonthoffset,discountdays, discount,discountdays2, discount2,
isnextbusinessday,isdefault,value,netday,isvalid, processing FROM c_paymentterm WHERE
ad_client_id='1000001';

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 181
5.10 Log Migration Script
There is one simple but powerful mechanism also done by Carlos Ruiz to record all
manual changes done to the ERP Application in the form of SQL scripts that are stored
in a location for easy transporting to any target instance for replication.

Previously we would use the 2Pack to export those changes and reimport them back.
2Pack allows better multi-package management, whereas Log Migration Script is used
at a single stage and then the scripts have to be serialised manually. Usually those
scripts are put in the migration folder of the trunk for others to download from and
apply to their instances so as to be up-to-date of the latest changes introduced by any
committer. As such, the changes it logs are meant to be version updates and not private
changes which is better taken care by the 2Pack. Migration scripts are noted
prominently and regarded as the latest version stage when there is a cut-off for the next
release. Figure 5.11 Preference Window Log Migration Script Checkbox

Development
When you're ready to
develop a trunk
enhancement, bug or
feature request that
requires migration scripts,
you need to open a session
and check the flag "Log
Migration Script" in
Preferences window. Please
note this parameter is not
saved between sessions - so
you need to check it any
time you are going to
develop something new for
the trunk:
This can be combined with
"Dictionary Maintenance"
to generate official
migration scripts, or used
alone to generate
customization migration
scripts.
After this you just continue
creating the needed

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 182
dictionary objects and Adempiere will generate the files with migration scripts in the temp directory of
your machine: in Windows Vista:

C:\Users\Carlos\AppData\Local\Temp\migration_script_postgresql.sql
C:\Users\Carlos\AppData\Local\Temp\migration_script_oracle.sql

in Windows XP
H:\Documents and Settings\user\Local Settings\Temp\migration_script_postgresql.sql
H:\Documents and Settings\user\Local Settings\Temp\migration_script_oracle.sql

The migration generated script looks like this:

-- Nov 11, 2007 1:54:50 AM COT


-- FR 1829798 - Easy generation of migration scripts
INSERT INTO AD_Message (AD_Client_ID,AD_Message_ID, AD_Org_ID,Created, CreatedBy,
EntityType, IsActive,MsgText, MsgTip,MsgType, Updated,UpdatedBy, Value) VALUES (0,53007,
0,TO_DATE('2007-11-11 01:54:49','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','Log Migration Script','Log
Migration Script - Save migration scripts file in %TEMP%/migration_script_*.sql',
'I',TO_DATE('2007-11-11 01:54:49', 'YYYY-MM-DD HH24:MI:SS'),100,'LogMigrationScript')
/

-- Nov 11, 2007 1:54:50 AM COT


-- FR 1829798 - Easy generation of migration scripts
INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip,
IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT
l.AD_Language,t.AD_Message_ID, t . M s g Te x t , t . M s g Ti p ,
'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language
l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N'
AND t.AD_Message_ID=53007 AND EXISTS (SELECT * FROM AD_Message_Trl tt WHERE
tt.AD_Language!=l.AD_Language OR tt.AD_Message_ID!=t.AD_Message_ID)
/

IMPORTANT NOTE: POSSIBLE PROBLEM: Even failed SQL statements are being logged.
Developer must review carefully the generated migration script for possible problems before committing.

Please note also these statements are not being logged:

SELECT
UPDATE AD_PROCESS SET STATISTIC_COUNT=

INSERT, DELETE OR UPDATE ON THE FOLLOWING TABLES:

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 183
AD_ACCESSLOG
AD_ALERTPROCESSORLOG Figure 5.12 Folder Structure of Migration Scripts
AD_CHANGELOG
AD_ISSUE
AD_LDAPPROCESSORLOG
AD_PACKAGE_IMP
AD_PACKAGE_IMP_BACKUP
AD_PACKAGE_IMP_DETAIL
AD_PACKAGE_IMP_INST
AD_PACKAGE_IMP_PROC
AD_PINSTANCE
AD_PINSTANCE_LOG
AD_PINSTANCE_PARA
AD_REPLICATION_LOG
AD_SCHEDULERLOG
AD_SESSION
AD_WORKFLOWPROCESSORLOG
CM_WEBACCESSLOG
C_ACCTPROCESSORLOG
K_INDEXLOG
R_REQUESTPROCESSORLOG
T_AGING
T_ALTER_COLUMN
T_DISTRIBUTIONRUNDETAIL
T_INVENTORYVALUE
T_INVOICEGL
T_REPLENISH
T_REPORT
T_REPORTSTATEMENT
T_SELECTION
T_SELECTION2
T_SPOOL
T_TRANSACTION

Migration Script Manager

This feature is part of the Migration Feature in ADempiere to allow complete facilitation
of distributing changes from one user to another easily and efficiently.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 184
As we developers all know, it's really hard to mantain a database in Adempiere while
working with many separate customizations. We have to deal with trunk / base
revision scripts to do the migration of our databases and such.

* To ease this process, Fernando Lucktemberg developed a functionality into Adempiere


that allows the Database changes to be managed in a much easier way.

What changes from actual behaviour

Actually, the migration scripts have a small header, that just explains why they were
made, and who created it. Usually, it has this info as SQL comments in the SQL header.

You open up your database manager, and then just apply the migration scripts.

What changes

* The new process here proposed has some differences from the actual process.

* To apply a migration script, you'll do it directly from Adempiere client, using the
System role to fulfill this activity.

* The process is separated into 3 basic steps.

o First, all the new migration scripts will have a new file skeleton, that will be like:

File Sample

File name : 001-tst.sql

>>>>>>>File starts here<<<<<<<

--BEGINHEADER--

INSERT INTO ad_migrationscript (ad_migrationscript_id, ad_client_id, ad_org_id, isactive, created,


createdby, updated, updatedby, NAME, description, projectname, releaseno, developername,
reference, url, filename, status, isApply)

VALUES (?, 0, 0, 'Y', '2008-01-01 01:00:00.0', 0, '2000-01-01 02:00:00.0', 0, 'Test2', 'This is a

test script2', 'Migration Scripts Automator', '340', 'fer_luck', '[FR 1234562]',

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 185
'http://www.faire.com.br', '001-tst.sql', 'IP', 'N');

--ENDHEADER--

--BEGINMS--

INSERT INTO test(test_id, ad_client_id, ad_org_id, isactive, created, createdby, updated, updatedby,
name, description, help, t_integer, t_number, t_date, t_datetime, c_uom_id, t_qty, c_currency_id,
t_amount, c_location_id, account_acct, c_payment_id, m_product_id, c_bpartner_id, m_locator_id,
processing, binarydata, processed, characterdata)

VALUES(106, 0, 0, 'Y', '2003-11-26 00:32:53.0', 100, '2000-01-01 00:00:00.0', 0, 'Doh', 'Test record
description', 'Test Comment', 10000002, 10000002, NULL, NULL, 100, 10000002, 195, 10000002, NULL,

NULL, NULL, NULL, NULL, NULL, 'N', NULL, 'N', '<html></html>');

INSERT INTO test(test_id, ad_client_id, ad_org_id, isactive, created, createdby, updated, updatedby,
name, description, help, t_integer, t_number, t_date, t_datetime, c_uom_id, t_qty, c_currency_id,
t_amount, c_location_id, account_acct, c_payment_id, m_product_id, c_bpartner_id, m_locator_id,
processing, binarydata, processed, characterdata)

VALUES(107, 0, 0, 'Y', '2003-11-26 00:32:53.0', 100, '2000-01-01 00:00:00.0', 0, 'Doh', 'Test record
description', 'Test Comment', 10000002, 10000002, NULL, NULL, 100, 10000002, 195, 10000002, NULL,
NULL, NULL, NULL, NULL, NULL, 'N', NULL, 'N', '<html></html>');

--ENDMS--

>>>>>>>File ends here<<<<<<<

Note that this new file has some new elements that we didn't use with the old approach.

Now we add a --BEGINHEADER-- and --ENDHEADER-- identifiers to tell the info we


need to know about each migration script to control how they're applied, and a --
BEGINMS-- and --ENDMS-- that identifies the begin and the end of the migration script
body.

Applying to Database

* Now that we have a new migration script, let's apply it against our database.

* To do that, we have to open Adempiere with the System Role, and then go into the
Application Dictionary folder.

* When in there, click over the Prepare Migration Script process.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 186
* A popup will ask you where you want to search for migration scripts (it will include
all the .sql files found in the directory), you should set a directory and then just press
the Ok button.

* After it's done, it will show you either a sucess message or error message, containing
the scripts that couldn't be applied.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 187
5.10 Centralized ID Management

This feature is used together with the above Log Migration Script. When multiple
developers make changes to the same core Application Dictionary, their useage of
primary key IDs of the system tables and fields has to be synchronised to avoid
redundant occurance and conflicts. This is now solved by having a central server that
keeps track and count of the IDs for each category of AD Model. Each registered
committer will setup their system to access that server to reserve their IDs to assign to
their new table and fields. This again is a contribution by Carlos Ruiz.

You need to configure the parameters in the System Configurator Window:

Figure 5.13 System Configurator to Register Committer Account

Especially the parameters:

DICTIONARY_ID_USER =
Your committer sourceforge ID

and

DICTIONARY_ID_PASSWORD =
Your committer assigned password

NOTE: If you're committer and


haven't received your password
please ask from Carlos Ruiz

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 188
(globalqss at sourceforge) e-mail

Development

Firstly, please configure the comment in the System Configurator window related to the
enhancement, bug or feature request you're solving, example:

Figure 5.14 Associating a Feature Request in the ID

When you're ready to develop a trunk enhancement, bug or feature request that
requires official dictionary ID's, you need to open a system session and check the flag
"Dictionary Maintenance" in Preferences window. Please note this parameter is not
saved between sessions - so you need to check it any time you are going to develop
something new for the trunk:

After this you just continue creating the needed dictionary objects and Adempiere will
assign the ID's from the centralized website developer.adempiere.com

The Log

If you want to review the log of used ID's for a table, you can navigate to the site:

http://developer.adempiere.com/cgi-bin/showlog?AD_Reference

Please replace the AD_Reference name with the table you want to see.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 189
IMPORTANT NOTE: When in "Dictionary Maintenance" mode all records for clients
System and GardenWorld will get centralized IDs

For Projects with Distributed Developers

If you conduct your own project with distributed developers - with distributed
development databases, then you have the same problem as ADempiere Committers to
synchronize the dictionary ID's.

This implementation can help also for these projects.

You just need to install the cgi scripts provided in:

http://adempiere.svn.sourceforge.net/viewvc/adempiere/contributions/stuff/
POC_Central_System_IDs/linux/

Set up a data directory ../data relative to cgi-bin directory for your project:

http://adempiere.svn.sourceforge.net/viewvc/adempiere/contributions/stuff/
POC_Central_System_IDs/linux/data/Adempiere/

Register your developers in the file data/PROJECT_NAME/RegisteredDevelopers.pwd

And set the system configurator parameters for project usage:

PROJECT_ID_USE_CENTRALIZED_ID = Y (default is N)

PROJECT_ID_WEBSITE = with the website provided for the centralized ID management

PROJECT_ID_PROJECT = name of the project set up

PROJECT_ID_USER = your user name for the project

PROJECT_ID_PASSWORD = your password committer for the project

PROJECT_ID_COMMENTS = the comment for the development you're attending

This will assign centralized ID's for all tables that have EntityType column, in the seed
those are:

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 190
AD_Column
AD_Element
AD_EntityType
AD_Field
AD_FieldGroup
AD_Form
AD_Image
AD_InfoColumn
AD_InfoWindow
AD_Menu
AD_Message
AD_ModelValidator
AD_Modification
AD_Process
AD_Process_Para
AD_Reference
AD_Ref_List
AD_Ref_Table
AD_ReplicationStrategy
AD_ReplicationTable
AD_ReportView
AD_Tab
AD_Table
AD_Task
AD_Val_Rule
AD_WF_NextCondition
AD_WF_Node
AD_WF_NodeNext
AD_WF_Node_Para
AD_WF_Responsible
AD_Window
AD_Workbench
AD_WorkbenchWindow
AD_Workflow
PA_ColorSchema
PA_MeasureCalc

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 191
FAQ

1. I will need to migrate some internal modifications to trunk, more exactly some
columns that have internal allocated IDs (> 1000000). What is the best way to get IDs
from IDs server without creating the columns (because i already have them, i just
need to change the IDs) ?

http://developer.adempiere.com/cgi-bin/get_ID?PROJECT= Adempiere&USER=
your_user&PASSWORD =your_password&TABLE =AD_Column&ALTKEY =
&COMMENT = Comment

Dissected :-)

http://developer.adempiere.com/

The website providing the ID's where cgi shells are installed

cgi-bin/get_ID

The shell that reserves ID's get_ID

?PROJECT=Adempiere

The project Adempiere (centralized ID can be used to manage IDs for other
projects but it needs some setup)

&USER=your_user

Your assigned user (normally the same as sourceforge)

&PASSWORD=your_password

Your assigned password

&TABLE=AD_Column

The table you want to reserve ID (in this example AD_Column - case sensitive!)

&ALTKEY=

Unused at this moment, to save alternate key for tables like Value
Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering
P a g e 192
&COMMENT=Comment -- the comments on the reservation

The result of the call is a page with the assigned ID.

To review the log you can call:

http://developer.adempiere.com/cgi-bin/showtaillog?AD_Column (NOTE: Or use


showlog for full log, recommended is to use showtaillog)

That's it, call the showlog.cgi with the table as parameter.

Revision
Here are revision and sound expert advice taken from Carlos Ruiz’s wikiversity
article[1].

Extension architecture
* Callouts
* Model Validator
* Java Triggers
* Processes
* Views and Reports
* Forms
* Print Formats
* Import File Loader

Common code
Context variables
Context variables are like 'global' variables for the whole Adempiere, or for a specific window or tab.

You can see all context variables in Tools -> Preference -> Context

Context variables starting with # are defined at login level

Every field in a window has his own context variable, you can access it programatically.

Reading context variable AD_Role_ID

int currole_id = Env.getContextAsInt(ctx, "#AD_Role_ID");

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 193
Creating object (new record, update record, delete record) [edit]

You can get or create objects from the database using the model classes, for example to read an
invoice from the database:

MInvoice inv = new MInvoice(getCtx(), invoice_id, get_TrxName());

This is equivalent to issue a 'SELECT * FROM C_Invoice' and load in memory the data.

To create a new record in the database you call the same code with zero as the ID:

MInvoice inv = new MInvoice(getCtx(), 0, get_TrxName());

You then can make changes to columns using the setter methods of the object, i.e.:

inv.setC_Currency_ID(100);

After you make all the changes you save the record in the database calling the method save():

inv.save();

The method save will execute an INSERT if is a new record or an UPDATE if the record already
exists. If you want to delete an existing record, you can call the method delete(), i.e.

inv.delete(true);

and after deleting you need to call the method save to execute the corresponding DELETE in the
database

Use messages for translations

To show messages within your programs, please use the i18n facility of Adempiere using the message
table for this purpose, programatically you simply execute, i.e.:

String dateLabel = Msg.getMsg(Env.getCtx(), "Date");

SQL
• Usage of embedded SQL – recommended to use UpperCase in SQL Keywords (for security sql
parser)
• Specially this keywords: SELECT, FROM, WHERE, ON, AS, INNER, JOIN, LEFT, OUTER, FULL

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 194
• When using joins, security parser also requires that ON clause defining the joining columns
must be enclosed in parenthesis
• use Oracle SQL standard syntax that can be translated to postgres – Don't use postgres specific
syntax

• If you want to issue a simple query returning just one column of the first record, you can use the
DB.getSQLValue functions provided by Adempiere:
• String sql = "SELECT COUNT(*) FROM C_Recurring_Run WHERE C_Recurring_ID=?";
• int current = DB.getSQLValue(get_TrxName(), sql, getC_Recurring_ID());

• To execute a DML operation in the database (INSERT, DELETE or UPDATE) you can use the
DB.executeUpdate method, i.e.:
• String sql = "UPDATE C_CashLine SET Processed='N' WHERE C_Cash_ID=" +
getC_Cash_ID();
• int noLine = DB.executeUpdate (sql, get_TrxName());

• To read several records from the database (cursor) you can execute
String sql = "SELECT C_PaymentAllocate_ID FROM C_PaymentAllocate WHERE
C_Payment_ID = ?";
PreparedStatement pstmt = null;
pstmt = DB.prepareStatement(sql, get_TrxName());
pstmt.setInt(1, payment_ID);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
payment_allocate_ID = rs.getInt(1);
/// ... more code
}
rs.close();
pstmt.close();

Commit (not common – used with transactions)


Normally you don't need to execute directly a commit. If in your process you need strict control of the
commit, please create a transaction:

Trx trx = Trx.get(getTrxName(ctx), true);


trx.commit()

Callouts
1. Called after user entered value (for Strings is called every keystroke)
2. It can be used for direct data validation – but you need to validate again before saving
3. Better usage for data consequences: i.e. Filling other fields with lookup values, calculating totals
You must repeat all calculations in persistence layer
4. You can have multiple callouts separated by ;

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 195
5. The processing of a callout must be quick (< 1 sec), if slow better create a button and process
6. Callout classes must extend CalloutEngine and implement the callout methods with 6 variables
(last optional)
* Context
* Window No
* Model Tab
* Model Field
* The new value
* The old value
* 'Returns' error message

7. There are also callouts for translation of strings on Import File Loader, these callouts have just one
parameter:
* The value
* 'Returns' the translated value

Exercise: Create a Callout on the Name of Product Category – the name must be passed to the
Description in upper case

Model Classes (lookup)


Persistence
1. PO (Persistent Object) --> X_<table> classes --> M<shortTable>
2. Class X_ is looked up with complete Name (and case) of the table
3. Class M is looked up with table name without prefix (if prefix is <= 2 char), and without
underscore symbols “_”

Precedence when looking up for M classes:


1. Look for model package of the entity type (for non-dictionary tables) – first look for M and then
X_
2. look for model package in:
org.compiere.model
org.compiere.wf
org.compiere.print
org.compiere.impexp
compiere.model
adempiere.model
org.adempiere.model

3. look for adempiere.model.X_ class


4. look for compiere.model.X_ class
5. look for org.compiere.model.X_ class

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 196
Exceptions:
AD_Element - M_Element
AD_Registration – M_Registration
AD_Tree – MTree_Base
R_Category – MRequestCategory
GL_Category – MGLCategory
K_Category – MKCategory
C_ValidCombination – MAccount
C_Phase – MProjectTypePhase
C_Task – MProjectTypeTask

• If can't find persistence class then it uses PO to save directly to the database.
• In Adempiere there is a GenericPO that can be used for programatically save tables with no model
class.
• X_ classes are generated automatically – don't change them

Usage of GenerateModel:
arguments:
* Output Directory - C:\srcAdempiere\trunk\base\src\org\compiere\model\
* Package - org.compiere.model
* EntityType - 'D'
* Optional table like - 'U_RoleMenu'

Model Classes (triggers)


• Insert/Update triggers: beforeSave and afterSave
• Delete triggers: beforeDelete and afterDelete

Model validator
Defined at client level
You can have multiple model validators separated by ;

Events:
* User Login – you know the user, role, client and organization – i.e. Useful for veto login

Events on table:
• BEFORE/AFTER
• NEW/ CHANGE/ DELETE

Events on documents:
• BEFORE/AFTER

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 197
• PREPARE/ VOID/ CLOSE/ REACTIVATE/ REVERSECORRECT/ REVERSEACCRUAL/
COMPLETE / POST

Model Classes vs Validators


• Don't customize adempiere model classes – implement triggers for official tables in model validator
• Use model classes (or model validator if preferred) for your customized tables
• Don't generate X_ classes for official adempiere tables – use general getter and setter from PO for
custom columns

Exercises:
• Create a ModelValidator that avoid users login twice in Adempiere
• Create a ModelValidator when Order change the business partner – add the previous bp to the
description
• Create a ModelValidator to forbid GardenAdmin to complete an Invoice
• Create a ModelValidator to avoid completely posting from invoices

Processes
• Called from menu or buttons
• prepare method for getting the parameters into variables – Record_ID just work for buttons
• doIt method for execution of the process
• addLog to keep log of the executions / for auditing purposes and showed at the end of the process
• return a message
• for errors must throw exceptions

Forms
Custom swing windows – special cases
Not recommended – not supported for webUI clients
* Extend org.compiere.swing.CPanel
* Swing code – implement listeners
* Use javax.swing and org.compiere.swing components

Import File Loader


* Stage table
* File definition
* Import of the file
* Import process to pass from the stage table to the definite tables

Exercise:
* Add POReference column to the I_Invoice stage table
* Change the ImportInvoice process to manage the import of this new column

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 198
Quiz
1. Describe briefly the different ways to port changes from one instance to another.

2. When should certain code be part of the core and when should it not be?

3. Describe one way to separate non-core functionality from core.

Glossary

Term Description

Model Validator A method to add functionality to a model validation process


without touching core, i.e. BeforeSave, we can still add an extra
task in another code stored away from the core.

Centralised ID The way to resolve ID conflicts in the Application Dictionary among


different developers issuing new IDs for their new tables.

PK / FK conflict Primary Key / Foreign Key conflict occurs when an instance is


getting the same PK ID value for 2 primary keys which must be
unique.

XML A file standard that is compatible with common programming


languages to persist data using tags.

Migration Script SQL scripts that record model changes in the database in between
version releases.

Meta-data Data about data, usually mean configuration details and is stored
as data rather than hard-coded

Patches.jar A jar to add to the application that will override particular core java
classes. It allows easier management of changes without
changing core directly.

JSR223 A java specification request standard that is implemented to allow


other scripting languages to talk to Java, i.e. Groovy, Python and
BeanShell.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 199
Summary
4. Software development is still very slow manual task and thus a high need for more
advanced tools or the riding on previous open source projects to cut down
development time.

5. There are many ways to extend the ERP application but they adhere to strict
discipline to avoid corrupting or breaking its horizontal core structure to be
compatible with the world’s very diverse localisation needs.

6. Localisation needs can be customised into its own jar to override core functions.

7. Model Validators group core changes to the documents’ models in a guarded manner
without impact to other users not needing such changes.

8. Callout is either in its own class or using metadata injection via JSR223 capability.

9. More scripting type metadata rules can be used in the Report and Processes feature.

10. 2Pack allows managing of changes in the form of packages that are transferable to
any other instance.

11. Log migration script is a feature to automatically generate SQL scripts for
application in any other instance that wishes to upgrade accordingly.

12. Centralized ID management is to avoid conflict of IDs when introducing new tables
or columns by other developers in the AD portion of the application.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 200
References
1. http://en.wikiversity.org/wiki/Extending_ADempiere

2. http://www.oslabs.org/index.php?
option=com_remository&Itemid=29&func=select&id=4
3. http://adempiere.svn.sourceforge.net/viewvc/adempiere/contributions/
Localizations/Colombia/packages/LCO_RetencionesBaseData/dict/PackOut.xml?
view=markup

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 201
Chapter 6 - Testing

Learning Objectives
By the end of this chapter, the student shall be able to:

1. Describe methods used in testing ADempiere code;

2. Explain the importance of testing in development;

3. Describe how a test mechanism can ensure quality assurance;

4. Demonstrate hands-on how ADempiere JUnit testing is done.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 202
Introduction
The ADempiere community has mutually agreed on the importance of testing to ensure
quality assurance in the ERP application software maintenance and development
process. There is now a strict awareness of self testing before any code is introduced or
changed in its source. Every commit must be submitted with a testimony or proof of a
test result carried out by a recognised testing method.

This is a sound principle of ‘getting things right the first time’ to avoid the higher cost of
maintaining poorly done code seeping into the whole application. As elaborated before,
a great part that goes towards good coding, is good coding practice and the reusing of
commonly accepted patterns. The ADempiere Best Practice wiki page[1] is vital to act as
a guide for all our developers to follow and learn from. It is a living dynamic document
where as more newer technology in testing emerges to simplify and hasten the tedious
boring testing process, any developer familiarizes with it and introduces it to the
community there. The Compiere sourcecode we inherited from are very well structured
and documented within the java classes. Most of our Java developers could follow and
understand the original intent and content before improving or maintaining them.

At the moment JUnit test classes are included in the project trunk for any developer to
reuse for their QA needs. There is a Hudson compiling testing server contributed and
maintained by Metas GmBH of Bonn, Germany that continously test compile each code
commit sent to the trunk.

However the use of tools is not a fool-proof testing environment. The more important
testing is still conventional practice of asking another user to test a particular change.
Finally when sourcecode is released daily to the open, the open global community of
users that constantly download, install and try out the applicaiton is our best testing
engine. They are an army that never sleeps that constantly provide bug reports and
feedback at every code commit to ensure bug creep is arrested early on. Not only that,
performance issues are included indirectly whenever a feedback points to any hiccup or
telltale signs coming from the many diverse users’ environments.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 203
Fitnesse Testing Framework
There is now a web enabled test framework from Fitnesse[2] that is quite user friendly
and hassle-free to setup. It allows test data cases to be stated in a wiki format that access
an online site to quickly return the test results. This will mean non-technical people can
now be involved in testing the application. Below is a sample test result done for
ADempiere:

Figure 6.1 Fitnesse page from test.adempiere.com

You can just go online to play with it here: http://www.testadempiere.com:8082/ and


choose the test from the left panel.

The Fitnesse Project was first started in February 2009, by Joel Stangeland with Carlos
Ruiz and Joel has documented the progress in the ADempiere wiki[3].

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 204
Hudson Build Server
If you suscribe to the CVSLog mailling list or relevant tracker in the ADempiere
Sourceforge project, you may get the following emails sent from the Hudson Build
Server setup by Metas GmBH in Germany.

Figure 6.2 Failure to build analysis from Hudson Server

Figure 6.3 Back to normal acknowledgement

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 205
The Hudson Build Server is very convenient to give a first level passing mark to any
commit that passes into trunk. This will ensure that the trunk must always compile
completely with all its object references made available. The way Hudson responds is
almost instantenous so to alert all the developers what just happened. Once the fault is
addressed, the Hudson server will issue a clean bill of normalcy.

During my visit to Bonn, Mark Ostermann, the CTO of Metas demonstrated to me how
versatile and powerful such test engines are in handling many instances of client
projects individually, to indicate what happened each time a new code commit takes
place. The screen will show graphically and color coded how each instance and module
is impacted in terms of individual code execution performance. The great thing is that
the testing software is open source and free-licensed.

Figure 6.4 Hudson used for ADempiere projects by Metas, Germany

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 206
Figure 6.4 Hudson performance test on ADempiere code

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 207
Logical Bugs
However the bugs or errors detected by such systems are merely syntax or reference
based and not logical based. A logical error is harder to detect and require human
discovery that follows a detailed specific operational task in the system to flush it out.
For example, let’s say that we are trying to calculate how many of a particular stocked
product is available for new orders. Such a figure may come from many sources and
categorised under many locators or warehouses or under different attributes. The
condition that makes an order reserving that product comes from documents namely
Orders and Shipments. Now such documents may be in a state of pending, confirmed
but reversed and termed for back-ordered i.e. if a complete line is not available it can be
broken up into separate shipment schedules. This very complex nature can affect the
last figure of availability of that said product. It will create a logical condition where the
data is not sufficiently clear and accurate to answer precisely under what conditions
that figure is pointing to. This is more of a weakness of the logic and limited data model
and not a hard bug. It has to be further engineered to include more detail properties of
the calculation and possibly a larger data model to include all those conditions
sufficiently. Be careful as some that seem to be bugs are actually features!

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 208
JUnit Testing
Eclipse where the
sourcecode is
modified does also
has its own JUnit
plugin to do code
testing.

Figure 6.4 JUnit sources

To execute the JUnit, you can simply right click on the test java and select Run As, JUnit
Test.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 209
Figure 6.5 Executing a JUnit Test class

You have to create each individual test class for each java code you are releasing. Eclipse
is equipped to automaticall help you generate new JUnit classes. But since there are
already numerous samples and test classes done by the ommunity in the trunk, you can
pick out a good example and reuse from there. They are located under the Extend folder
of the trunk.

Each test class has to extend AdempiereTestCase which extends TestCase. The parent
class will resolve the ADempiere context and environment such as its database access
properties for any test to process through and work with the database model.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 210
Figure 6.6 Junit Test Result

The above test FunctionalBPartnerTest ran successfully so that it gives a green coloured
banner on the top left panel with 0 errors or failures. It also gives the time clocked
during the test.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 211
Quiz
1. Why is testing important before software is released?

2. What kind of bugs are there?

3. How is JUnit used in the ADempiere project?

Glossary

Term Description

Hudson Server A build server that continously test committed code in the trunk to
ensure they are without syntax and reference errors.

Best Practice An agreed path or conduct to follow by most members due to its
consistent successful or clear guidelines.

Bug A condition in the software whiches causes an error during


operation or testing. There are many types of bugs. Some are
fatal, some are intermittent and some are logical and not due to
any faulty programming syntax

Fatal Bug Bug that will corrupt important data and failed the smooth running
of the system. Or return results that are not desired.

Intermittent Bugs Bugs that are not repeatable easily and occur only under different
conditions or operating environment. A bug should be repeatable
under specified conditions to be termed a bug.

Bug Day A declared agreed day by the community to work on bugs


together, in order to make the software fit for the next release.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 212
Summary
1. Testing is important QA pre-requisite before any new or changed code is committed
into the project.

2. Many of the testing tools are from open source such as Finnesse and Hudson.

3. JUnit is already incorporated into Eclipse and there are test classes contributed for
reusing during class testing.

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 213
References
1. http://www.adempiere.com/index.php/ADempiere_Best_Practices

2. http://www.adempiere.com/index.php/Fitnesse_use_in_adempiere

3. http://www.adempiere.com/index.php/TestFramework

Copyright (C) 2009 Redhuan D. Oon ERP Software Engineering


P a g e 214

Vous aimerez peut-être aussi