Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This tutorial is designed for beginners with little or no OFBiz experience. It covers the fundamentals of the OFBiz application development process. The goal is to make a developer conversant with best practices, coding conventions, basic control flow, and all other aspects which that a developer needs for OFBiz customization.

This tutorial will help you in building your first "Demo Application" in OFBiz.

Info
titleImportant!

Post your questions to the OFBiz User Mailing List. Details about the mailing lists are available here


Info
titlePre-Requisites
  • For the Trunk version, the ofbiz-framework trunk and ofbiz-plugins trunk the minimum requirement you need to be installed is Java 1.8 SDK or Sun JDK 1.8.
  • Apache OFBiz can be downloaded and run on both Unix-based and Windows-based systems.
  • Set JAVA_HOME environment variable (It is required to run Gradle build tool)
    Execute the following command on terminal: echo $JAVA_HOME (this will show a path(i.e home directory of your Java installation) which means the variable is set and if not please set)
  • System specific requirements are available here.


Info
titleThis tutorial is for trunk release. For release specific tutorials, please refer:

The branch-specific naming convention is taken based on the year and month in which the branch has been created.
For example Release 18.12 - Here 18 represents the Year 2018 and 12 represents to 12th Month(i.e December). The latest branch is the greatest branch and is highly recommended for general-purpose use.

...

Info
titleImportant!

For any questions or concerns, please use OFBiz User Mailing List. Details about the mailing lists are available here.

Info
This tutorial is for trunk release. For release specific tutorials, please refer
children


Info
titleSource Code!

Apache OFBiz
Download Apache OFBiz®
OFBiz Source Repository and Access

Tutorial
The source code of the Practice Application demonstrated in this tutorial can be downloaded from [TODO].

Framework Introduction Videos
OFBiz YouTube Channel or Vimeo can be accessed for the same.

...

The architecture alone makes it easier for you to customize the applications to your needs, but many of the best flexibility points in the system would be meaningless and even impossible if the system was not distributed as open-source software. OFBiz is licensed under the Apache License Version 2.0 (ASL2) which grants you the right to customize, extend, modify, repackage, resell, and many other potential uses of the system.

No restrictions are placed on these activities because we feel that they are necessary for the effective use of this type of software. Unlike other open-source licenses, such as the GPL, your changes do not have to be released as open-source. There are obvious benefits to contributing certain improvements, fixes, and additions back to the core project, but some changes will involve proprietary or confidential information that must not be released to the public. For this reason, OFBiz uses the ASL2 which does not require this. The only required thing is to not remove the "copyright, patent, trademark, and attribution notices" you find in files. For more information on open source licenses see the Open Source Initiative (OSI) website at www.opensource.org.

Another benefit of this open-source model is that we receive constant feedback from those who are using the software. We have received countless bug fixes, improvement suggestions, and best-practice business advice from users and potential users of OFBiz. Many of the greatest features in the project were inspired by some comment comments or suggestion suggestions sent to the mailing lists associated with the project. With dozens of organizations using the software and probably hundreds of deployed sites using one piece or another of the project we generally get 20-30 emails each day about the project.

To make sure our functionality is timely and useful we always start by researching public standards and common usage for any component we are working on. This helps us support and use common vocabularies and gives us an instant breadth of options and features that can only be achieved through standards processes and other group efforts. It also opens doors in the future for flexible communication with other systems that are built around the same standards, both inside your organization and in the partner or other organizations.

The applications and application components that come with the system provide you with a broad and flexible basis that can be used as-is with the best-practices-based designs or customized to your own special needs. The applications facilitate the management of everything from parties and products to accounting, customer service, and internal resource and asset management.

...

If you haven't already checkout Apache OFBiz Framework on your machine, let's do it. Anyone can checkout or browse the source code in the OFBiz public Subversion (SVN) GIT repository. If you don't have SubversionGit, to install it you can go here for instructions.

To checkout the To clone the source code, simply use the following command (if you are using a GUI client, configure it appropriately):

Since the trunk was split into ofbiz-framework and ofbiz-plugins, the specialpurpose and hot-deploy directories have disappeared.
New components must be put in a plugins directory which works as was the hot-deploy directory.

For OFBiz existing components, check them out using the Gradle tasks below. or the GIT command

1.Checkout via Gradle tasks

To get all components use pullAllPluginsSource(This command should be run from ofbiz-framework home). Beware this deletes a previously existing plugins directory.

Code Block
For Linux/Mac: $ ./gradlew pullAllPluginsSource
For Windows: > gradlew pullAllPluginsSource

2.Checkout via GIT command(Following commands should be run from ofbiz-framework home)

For more details refer Apache OFBiz Source Repository page.

...

  • framework components: These are lower level components that provides the technical layer and tools to the application components; the features provided by these components are typically the ones provided by any other development framework (data layer, business logic layer, transaction handling, data source pools, etc…)
  • application components: These are generic business components required for ERP applications that can be extended/customized (product, order, party, manufacturing, accounting etc…); application components have access to the services and tools provided by the framework components and to the services published by other application componentcomponents.
  • plugins components: These components are similar as applications to application components but meant for special purpose applications like ecommerce, google base integration, eBay integration etc.

...

It's very easy to setup a new custom component in OFBiz in plugins directory. Using the command line you just need run the following command.


Code Block
$ ./gradlew createPlugin -PpluginId=ofbizDemo


Image RemovedImage Added

Running your first application

...

  1. Simply open $OFBIZ_HOME/plugins/ofbizDemo/widget/OfbizDemoScreens.xml file from ofbizDemo plugin (you just created)


    Code Block
    languagexml
    <?xml version="1.0" encoding="UTF-8"?>
    <screens xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/widget-screen.xsd">
        <screen name="main">
            <section>
                <actions>
                    <set field="headerItem" value="main"/><!-- this highlights the selected menu-item with name "main" -->
                </actions>
                <widgets>
                    <decorator-screen name="OfbizDemoCommonDecorator" location="${parameters.mainDecoratorLocation}">
                        <decorator-section name="body">
                            <label text="Hello World!! :)"/>
                        </decorator-section>
                    </decorator-screen>
                </widgets>
            </section>
        </screen>
    </screens>

    We have only added the <label text="Hello World!! :)" />

  2. Now you will need to restart OFBiz by reloading data(./gradlew loadAll ofbiz). It's required as you have created a new component with some security data for you component (Setup by default in your component data directory as OfbizDemoSecurityGroupDemoData.xml) and as you will restart it, ofbizdemo component will also be loaded.

  3. As OFBiz restarted direct your browser to your application here https://localhost:8443/ofbizDemo
  4. You will be asked to login. Login with user: admin password: ofbiz.
  5. As you login, you will see ofbizdemo application up with the hello world message you have put in screen as shown in below given image.



    That's it, congratulations your first component is setup and running!!

...

Services using other engines

Whenever you have to build a business logic you should prefer to write services to leverage features from its built in Service Engine.

The service "createOfbizDemo" that you created earlier was using engine="entity-auto" and hence you didn't need to provide its implementation and OFBiz took care of create operation.  When you need to work on complex operations in service involving multiple entities from database and custom logics to be built, you need to provide custom implementation to your service. In this section we will focus on this.

Service in Java

You can implement a service in Java as directed here in below given steps:

1.) Define your service, here again we will be operating on the same entity(OfbizDemo) of our custom Ofbiz Demo application. Open your service definition file $OFBIZ_HOME/plugins/ofbizDemo/servicedef/services.xml and add a new definition as:


Code Block
languagexml
titleservices.xml
 <service name="createOfbizDemoByJavaService" default-entity-name="OfbizDemo" engine="java"
        location="com.companyname.ofbizdemo.services.OfbizDemoServices" invoke="createOfbizDemo" auth="true">
    <description>Create an Ofbiz Demo record using a service in Java</description>
    <auto-attributes include="pk" mode="OUT" optional="false"/>
    <auto-attributes include="nonpk" mode="IN" optional="false"/>
    <override name="comments" optional="true"/>
</service>


Info

Notice we have this time used engine="java".


2.) Create package "com.companyname.ofbizdemo.services" in your ofbizDemo components src/main/java directory (create those if they don't exist in your src directory). 

 Example: src/main/java/com/companyname/ofbizdemo/services. Services for your application which have to be implemented in Java can be placed in this java directory.

3.) Define new Java Class in file OfbizDemoServices.java here in services directory and implement method, which is going to be invoked by your service definition, as shown below:


Code Block
languagejava
titleOfbizDemoServices.java
package com.companyname.ofbizdemo.services;
import java.util.Map;
 
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.service.DispatchContext;
import org.apache.ofbiz.service.ServiceUtil;
 
public class OfbizDemoServices {
 
    public static final String module = OfbizDemoServices.class.getName();
 
    public static Map<String, Object> createOfbizDemo(DispatchContext dctx, Map<String, ? extends Object> context) {
        Map<String, Object> result = ServiceUtil.returnSuccess();
        Delegator delegator = dctx.getDelegator();
        try {
            GenericValue ofbizDemo = delegator.makeValue("OfbizDemo");
            // Auto generating next sequence of ofbizDemoId primary key
            ofbizDemo.setNextSeqId();
            // Setting up all non primary key field values from context map
            ofbizDemo.setNonPKFields(context);
            // Creating record in database for OfbizDemo entity for prepared value
            ofbizDemo = delegator.create(ofbizDemo);
            result.put("ofbizDemoId", ofbizDemo.getString("ofbizDemoId"));
            Debug.log("==========This is my first Java Service implementation in Apache OFBiz. OfbizDemo record created successfully with ofbizDemoId:"+ofbizDemo.getString("ofbizDemoId"));
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError("Error in creating record in OfbizDemo entity ........" +module);
        }
        return result;
    }
}


4.) Stop server and re-start using "./gradlew ofbiz", it will compile your class and will make it available when ofbiz restarts which updated jar file.

5.) Test service implemented using webtools --> Run Service option(https://localhost:8443/webtools/control/runService) or simply update the service name being called by your controller request to use this service instead and use add form in your app that you prepared earlier. By doing this your Add OfbizDemo form will call this java service.


Code Block
languagexml
<request-map uri="createOfbizDemo">
    <security https="true" auth="true"/>
    <event type="service" invoke="createOfbizDemoByJavaService"/>
    <response name="success" type="view" value="main"/>
</request-map>


To make sure this new service implementation is being executed, you can check this line in console log that you have put in your code using Debug.log(....). For logging in OFBiz you must always use Debug class methods in Java classes.


Code Block
languagejava
titleConsole Log
[java] 2014-06-24 12:11:37,282 (http-bio-0.0.0.0-8443-exec-2) [  OfbizDemoServices.java:28 :INFO] ==========This is 
my first Java Service implementation in Apache OFBiz. OfbizDemo record created successfully with ofbizDemoId: ......


Service in Groovy

To utilize feature of on the fly compilation and less line of code you can implement services for building business logics in OFBiz using Groovy DSL.

To implement a service using Groovy you can follow below given steps:

1.) Add new service definition to services/services.xml file as:


Code Block
languagexml
titleservices.xml
<service name="createOfbizDemoByGroovyService" default-entity-name="OfbizDemo" engine="groovy"
        location="component://ofbizDemo/scriptgroovyScripts/com/companyname/ofbizdemo/OfbizDemoServices.groovy" invoke="createOfbizDemo" auth="true">
    <description>Create an Ofbiz Demo record using a service in Groovy</description>
    <auto-attributes include="pk" mode="OUT" optional="false"/>
    <auto-attributes include="nonpk" mode="IN" optional="false"/>
    <override name="comments" optional="true"/>
</service>


2.) Add new groovy services file here  component://ofbizDemo/script/com/companynamegroovyScripts/ofbizdemo/OfbizDemoServices.groovy

3.) Add service implementation to the file OfbizDemoServices.groovy

Code Block
languagegroovy
titleOfbizDemoServices.groovy
import org.apache.ofbiz.entity.GenericEntityException;

def createOfbizDemo() {
    result = [:];
    try {
        ofbizDemo = delegator.makeValue("OfbizDemo");
        // Auto generating next sequence of ofbizDemoId primary key
        ofbizDemo.setNextSeqId();
        // Setting up all non primary key field values from context map
        ofbizDemo.setNonPKFields(context);
        // Creating record in database for OfbizDemo entity for prepared value
        ofbizDemo = delegator.create(ofbizDemo);
        result.ofbizDemoId = ofbizDemo.ofbizDemoId;
        logInfo("==========This is my first Groovy Service implementation in Apache OFBiz. OfbizDemo record "
                  +"created successfully with ofbizDemoId: "+ofbizDemo.getString("ofbizDemoId"));
      } catch (GenericEntityException e) {
          logError(e.getMessage());
          return error("Error in creating record in OfbizDemo entity ........");
      }
      return result;
}


4.) Stop server and re-start using"./gradlew ofbiz", this time we just need to load the new service definition, no explicit compilation is required as its a service implementation in Groovy.

5.) Test service implemented using webtools --> Run Service option(https://localhost:8443/webtools/control/runService) or simply update the service name being called by your controller request to use this service instead and use add form in your app that you prepared earlier for testing. By doing this your Add OfbizDemo form will call this groovy service.


Code Block
languagexml
titlecontroller.xml
<request-map uri="createOfbizDemo">
    <security https="true" auth="true"/>
    <event type="service" invoke="createOfbizDemoByGroovyService"/>
    <response name="success" type="view" value="main"/>
</request-map>


To make sure this new service implementation is being executed, you can check this line in console log that you have put in your code using Debug.log(....). For logging in OFBiz you must always use Debug class methods in Java classes.


Code Block
languagejava
titleConsole Log
[java] 2014-06-24 12:11:37,282 (http-bio-0.0.0.0-8443-exec-2) [  OfbizDemoServices.java:28 :INFO] ==========This is my 
first Groovy Service implementation in Apache OFBiz. OfbizDemo record created successfully with ofbizDemoId: .....


To get more details around using Groovy DSL for service and events implementation in Apache OFBiz you can refer document created by Jacopo Cappellato in OFBiz Wiki here.

...

2.) Add new Groovy file for data fetching logic at location $ OFBIZ_HOME/plugins/ofbizDemo/webapp/ofbizDemo/WEB-INF/actions/groovyScripts/crud/ListOfbizDemo.groovy and add code as shown to list out OfbizDemo records:

...


Code Block
languagexml
titleOfbizDemoScreens.xml
<screen name="AddOfbizDemoFtl">
    <section>
        <actions>
            <set field="titleProperty" value="PageTitleAddOfbizDemos"/>
            <set field="headerItem" value="addOfbizDemoFtl"/>
            <script location="component://ofbizDemo/webapp/ofbizDemo/WEB-INF/actionsgroovyScripts/crud/ListOfbizDemo.groovy"/>
        </actions>
        <widgets>
            <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">
                <decorator-section name="body">
                    <screenlet title="${uiLabelMap.OfbizDemoListOfbizDemos}">
                        <platform-specific>
                            <html><html-template location="component://ofbizDemo/webapp/ofbizDemo/crud/ListOfbizDemo.ftl"/></html>
                         </platform-specific>
                    </screenlet>
                    <screenlet title="${uiLabelMap.OfbizDemoAddOfbizDemoServiceByFtl}">
                        <platform-specific>
                            <html><html-template location="component://ofbizDemo/webapp/ofbizDemo/crud/AddOfbizDemo.ftl"/></html>
                        </platform-specific>
                    </screenlet>
                </decorator-section>
            </decorator-screen>
        </widgets>
    </section>
</screen>

4.) Add new controller request and a new item for OfbizDemo menu as:

...


<screen name="AddOfbizDemoFtl">
    <section>
        <actions>
            <set field="titleProperty" value="OfbizDemoAddOfbizDemoFtl"/>
            <set field="headerItem" value="addOfbizDemoFtl"/>
        </actions>
        <widgets>
            <decorator-screen name="OfbizDemoCommonDecorator" location="${parameters.mainDecoratorLocation}">
                <decorator-section name="body">
                     <label style="h4" text="${uiLabelMap.OfbizDemoListOfbizDemos}"/>
                     <platform-specific>
                         <html><html-template location="component://ofbizDemo/webapp/ofbizDemo/crud/ListOfbizDemo.ftl"/></html>
                     </platform-specific>
                     <label style="h4" text="${uiLabelMap.OfbizDemoAddOfbizDemoFtl}"/>
                     <platform-specific>
                         <html><html-template location="component://ofbizDemo/webapp/ofbizDemo/crud/AddOfbizDemo.ftl"/></html>
                     </platform-specific>
                </decorator-section>
            </decorator-screen>
        </widgets>
    </section>
</screen>


...

Now you are ready to dive in. Welcome to OFBiz world.

Children Display
alltrue