This tutorial explains how to run Service Builder and provides an overview of
the code that Service Builder generates. If you’d like to use Service Builder in
your application but haven’t yet created a service.xml
file, please see the
Defining an Object-Relational Map with Service Builder
tutorial and then come back to this one.
Running Service Builder
To build a service from a service.xml
file, you can use Liferay IDE,
Liferay Developer Studio, or use a terminal window. In this tutorial, we refer
to the Event Listing example project that’s referenced throughout the Liferay
Service Builder tutorials. You can find the Event Listing example project on
Github.
Now let’s learn how to run Service Builder.
Using Liferay IDE or Developer Studio: From the Package Explorer, open the
service.xml
file from your [plugin-project]/docroot/WEB-INF
folder. By
default, the file opens up in the Service Builder Editor. Make sure you are in
Overview mode. Then click the Build Services button near the top-right corner
of the view. The Build Services button has an image of a document with the
numerical sequence 010 in front of it.
Make sure to click the Build Services button and not the Build WSDD button that appears next to it. Building the WSDDs won’t hurt anything, but you’ll generate files for the remote service instead of the local one. For information about WSDDs (web service deployment descriptors), please refer to the Working with SOAP Web Services tutorial.
Another simple way to run Service Builder is to right-click on your project’s name in the Package Explorer and then to select Liferay → Build Services (or, equivalently, Liferay → SDK → build-service).
When you run Service Builder from Liferay IDE or Developer Studio, your IDE
generates a build.[username].properties
file in your Plugins SDK, where
[username]
is your operating system username. This file is used to specify the
location of a Liferay instance. Your Plugins SDK needs to be configured with the
location of a Liferay instance since it needs to compile your code against
classes on Liferay’s classpath. Here’s a sample build.[username].properties
file generated by Liferay IDE:
#Managed by Liferay IDE (remove this comment to prevent future updates)
#Wed Jan 21 17:45:20 EST 2015
app.server.tomcat.lib.global.dir = [...]/liferay-portal-[version]/tomcat-7.0.42/lib/ext
app.server.tomcat.deploy.dir = [...]/liferay-portal-[version]/tomcat-7.0.42/webapps
app.server.parent.dir = [...]/liferay-portal-[version]
app.server.tomcat.dir = [...]/liferay-portal-[version]/tomcat-7.0.42
app.server.type = tomcat
app.server.tomcat.portal.dir = [...]/liferay-portal-[version]/tomcat-7.0.42/webapps/ROOT
After running Service Builder, the Plugins SDK prints messages listing the
generated files and a message stating BUILD SUCCESSFUL
. More information about
the generated files appears below.
Using the terminal: Open a terminal window and navigate to your Plugins
SDK directory. If a build.[username].properties
does not exist in your Plugins
SDK directory, create one. Don’t edit the build.properties
file itself. Your
build.[username].properties
file can override any of the properties specified
in the build.properties
file. In your build.[username].properties
file, add
at least the following line:
app.server.parent.dir = [...]/liferay-portal-[version]
If you’re using a Liferay Tomcat bundle, it’s usually not necessary to override
all of the properties that Liferay IDE and Developer Studio override. Specifying
the value of the app.server.parent.dir
property suffices as long you haven’t
changed the relative locations of the app.server.tomcat.*
directories.
When you’ve finished configuring your build.[username].properties
file,
navigate to your portlets/event-listing-project-portlet
directory and enter
this command:
ant build-service
When the service has been successfully generated, a BUILD SUCCESSFUL
message
appears in your terminal window. You should also see that a large number of
files have been generated in your project. These files include a model layer,
service layer, and persistence layer. Don’t worry about the number of generated
files–you’ll never have to customize more than three of them. To review the
code that Service Builder generates for your entities, see the next section.
Understanding the Code Generated by Service Builder
Let’s examine the files Service Builder generates for your entity. Note that the
files listed under Local Service and Remote Service below are only generated for
an entity that has both local-service
and remote-service
attributes set to
true
. Service Builder generates services for these entities in two locations
in your project. These locations use the package path that you specified in your
service.xml
file. For the Event Listing project, these two locations are the
following ones:
docroot/WEB-INF/service/com/liferay/docs/eventlisting
docroot/WEB-INF/src/com/liferay/docs/eventlisting
The docroot/WEB-INF/service/com/liferay/docs/eventlisting/
package
contains utility classes and interfaces for the Event Listing project. All the
classes and interfaces in the service folder are packaged in a .jar
file
called event-listing-project-portlet-service.jar
, in the project’s
docroot/WEB-INF/lib
folder. This .jar
file is generated whenever you run
Service Builder. It’s possible to place this .jar
file on your application
server’s global classpath to make your project’s services available to other
projects. This practice, however, is not recommended. Doing so would allow
portlets in different project, for example, to create, update, and delete Entity
and Location entities. You should seriously consider the security implications
of placing your project’s service .jar
file on your application server’s
global classpath. Do you really want to allow other plugins to access your
project’s services?
The docroot/WEB-INF/src/com/liferay/docs/eventlisting
package contains the
implementation of the interfaces defined in the
docroot/WEB-INF/service/com/liferay/docs/eventlisting
package. It belongs
to the Event Listing project’s classpath but is not available outside the Event
Listing project. Service Builder generates classes and interfaces belonging to
the persistence layer, service layer, and model layer in the
docroot/WEB-INF/service/com/liferay/docs/eventlisting
and
docroot/WEB-INF/src/com/liferay/docs/eventlisting
packages. Let’s look at
the classes and interfaces generated for Events. The ones generated for
Locations are similar. You won’t have to customize more than three classes for
each entity. These customizable classes are *LocalServiceImpl
, *ServiceImpl
,
and *ModelImpl
.
-
Persistence
EventPersistence
: Event persistence interface that defines CRUD methods for the Event entity such ascreate
,remove
,countAll
,find
,findAll
, etc.EventPersistenceImpl
: Event persistence implementation class that implementsEventPersistence
.EventUtil
: Event persistence utility class that wrapsEventPersistenceImpl
and provides direct access to the database for CRUD operations. This utility should only be used by the service layer; in your portlet classes, useEventLocalServiceUtil
orEventServiceUtil
instead.
-
Local Service (generated for an entity only if an entity’s
local-service
attribute is set totrue
inservice.xml
)EventLocalService
: Event local service interface.EventLocalServiceImpl
(LOCAL SERVICE IMPLEMENTATION): Event local service implementation. This is the only class in the local service that you should modify manually. You can add custom business logic here. For any custom methods added here, Service Builder adds corresponding methods to theEventLocalService
interface the next time you run it.EventLocalServiceBaseImpl
: Event local service base implementation. This is an abstract class. Service Builder injects a number of instances of various service and persistence classes into this class.@abstract
EventLocalServiceUtil
: Event local service utility class which wrapsEventLocalServiceImpl
and serves as the primary local access point to the service layer.EventLocalServiceWrapper
: Event local service wrapper which implementsEventLocalService
. This class is designed to be extended and it allows developers to customize the local Event services. Customizing services should be done via a hook plugin.
-
Remote Service (generated for an entity only if an entity’s
remote-service
attribute is not set tofalse
inservice.xml
)EventService
: Event remote service interface.EventServiceImpl
(REMOTE SERVICE IMPLEMENTATION): Event remote service implementation. This is the only class in the remote service that you should modify manually. Here, you can write code that adds additional security checks and invokes the local services. For any custom methods added here, Service Builder adds corresponding methods to theEventService
interface the next time you run it.EventServiceBaseImpl
: Event remote service base implementation. This is an abstract class.@abstract
EventServiceUtil
: Event remote service utility class which wrapsEventServiceImpl
and serves as the primary remote access point to the service layer.EventServiceWrapper
: Event remote service wrapper which implementsEventService
. This class is designed to be extended and it allows developers to customize the remote Event services. Customizing services should be done in a hook plugin.EventServiceImpl
EventServiceSoap
: Event SOAP utility which the remoteEventServiceUtil
remote service utility can access.EventServiceUtil
EventSoap
: Event SOAP model, similar toEventModelImpl
.EventSoap
is serializable; it does not implementEvent
.
-
Model
EventModel
: Event base model interface. This interface and itsEventModelImpl
implementation serve only as a container for the default property accessors generated by Service Builder. Any helper methods and all application logic should be added toEventImpl
.EventModelImpl
: Event base model implementation.Event
: Event model interface which extendsEventModel
.EventImpl
: (MODEL IMPLEMENTATION)Event model implementation. You can use this class to add helper methods and application logic to your model. If you don’t add any helper methods or application logic, only the auto-generated field getters and setters are available. Whenever you add custom methods to this class, Service Builder adds corresponding methods to theEvent
interface the next time you run it.EventWrapper
: Event wrapper, wrapsEvent
.
Each file that Service Builder generates is assembled from an associated
Freemarker template. You can find Service Builder’s Freemarker templates in the
com.liferay.portal.tools.servicebuilder.dependencies
package of Liferay’s
portal-impl/src
folder. For example, if you want to find out how a
*ServiceImpl.java
file is generated, just look at the service_impl.ftl
template.
Of all the classes generated by Service Builder, only three should be manually
modified: *LocalServiceImpl
, *ServiceImpl
and *Impl
. If you manually
modify the other classes, your changes are overwritten the next time you run
Service Builder. Whenever you add methods to, remove methods from, or change a
method signature of a *LocalServiceImpl
class, *ServiceImpl
class, or
*Impl
class, you should run Service Builder again to regenerate the affected
interfaces and the service JAR.
Related Topics
Running Service Builder and Understanding the Generated Code