Sencha Inc. | HTML5 Apps


Productive Enterprise Web Development with Ext JS and Clear Data Builder

April 22, 2013 | Viktor Gamov

Guest Blog Post

It’s not likely that you’ll start developing an enterprise HTML5 application without using one of the JavaScript frameworks. One of the most feature complete frameworks is Sencha Ext JS. Farata Systems has developed an open source software tool called Clear Toolkit for Ext JS. Clear Toolkit includes an Eclipse plugin called Clear Data Builder. This is a productivity tool — a code generator — that can create a CRUD application for you in no time. This application has an HTML/JavaScript/Ext JS client and Java-based server. In this article, you will learn how to jumpstart development of enterprise web applications.

Learn the latest about Ext JS and HTML5/JavaScript for three intensive days with 60+ sessions, 3+ parties and more at SenchaCon 2013. Register today!

Part One: Ext JS MVC Application Scaffolding

In Part One, I’ll cover the following topics:

  • What is Clear Toolkit for Ext JS
  • How to create an Ext JS MVC application for a Java-based project
  • How to deploy and run your first Ext JS + Java application on Apache Tomcat server

Clear Toolkit for Ext JS contains the following parts:

  • Clear Data Builder (CDB) — Eclipse plugin that supports code generation of Ext JS MVC artifacts based on Java code. CDB comes with wizards to start a new project with plain Java or with popular frameworks like Hibernate, Spring, MyBatis.
  • Clear JS — a set of JavaScript components that extend Ext JS standard components. For example, Clear JS contains
  • ChangeObject — a universal way to trace the state changes between old and new versions of the same item in a store.
  • Clear Runtime — Java components that implement the server side of ChangeObject, DirectOptions, etc.

CDB helps you to be more productive which means you write less code and produce results faster. You’ll see how CDB helps you to integrate the client side with the back-end using RPC style and how to implement data pagination for your application.

CDB distribution is available as a plugin for Eclipse IDE. You can download CDB here. The current version is 4.1.4. You can install this plugin via the Install New Software menu in the Eclipse IDE. Figure 1 shows how you can validate the plugin installation. If you see “Clear Data Builder for Ext JS feature” in the list of Installed Software in your Eclipse IDE, you’re good to go.

Important: You must have “Eclipse for Java EE Developers” installed, which includes the plugins for automation of the Web applications.

Farata Systems

Figure 1. Verifying CDB Installation

Clear Data Builder comes with a set of prepared examples that demonstrate the integration with popular Java frameworks — MyBatis, Hibernate, and Spring. Also, a plain Java project example that doesn’t use any of the frameworks is available. Let’s start with the creation of a new project by selecting the menu File → New → Other → Clear, and then press Next.

Farata Systems

Figure 2. New CDB Project Wizard

First, let’s call the new project episode_1_intro. CDB supports different ways of linking the Ext JS framework to the application. In my case, I have already installed Ext JS libraries under my Web server (Apache Tomcat). I’m going to use this local Ext JS URL, but you can just specify any folder on your machine, and CDB will copy the Ext JS file inside your project. Lastly, you can use Ext JS from the Sencha CDN, if you don’t want to store these libraries inside your project. Besides, using a common CDN will allow the Web browser to reuse the cached version of Ext JS.

For this project, we are not going to use any server side platform (like MyBatis or Hibernate). Just click the Finish button. First, CDB will print some initial messages on the Eclipse console. When CDB runs for the first time, it initializes a directory structure in the WebContent folder. Inside the WebContent directory, CDB creates a directory structure, which is recommended by Sencha for MVC applications. Also, you’ll get the HTML wrapper — index.html — for this application, which contains the link to the entry point of our application.

CDB generates an empty project with one sample controller and one view — Viewport.js. To run this application, you need to add the newly generated Dynamic Web Project to Tomcat and start the server (right-click on the Tomcat in the Servers view of Eclipse).

Farata Systems

Figure 3. Adding a Web Project to Tomcat

Let’s switch to the web browser to open this application on http://localhost:8080/episode_1_intro . Voila! In just a couple of minutes, we’ve set up a new Dynamic Web Project with the Ext JS framework support and one fancy button on the UI.

Farata Systems

Figure 4. Running a Scaffolded Application

The next step is to make something useful out of this basic application.

Part Two: Generating a CRUD Application

CRUD stands for Create-Retrieve-Update-Delete. It’s a well-known term for describing the applications that support data manipulation. The apps can retrieve data from some data source and update the data too.

In Part Two, I’ll cover the following topics:

  • Create a simple CRUD Ext JS + Java application
  • Create a POJO and the corresponding
  • Create a Java service and populate with data from the service
  • Use the auto-generated Ext JS application
  • Extend the auto-generated CRUD methods
  • Use ChangeObject

Now, I would like to show you how to use CDB to create a CRUD application. I’ll show you how you can turn your Java POJO class into the Ext JS model. I’ll explain the following:

  • How you can populate the Ext JS store from a remote service
  • How you can use automatically generated UI for that application
  • How you can extend it
  • How to use the ChangeObject class

I will extend the application from Part 1. For my CRUD application, I need a Java POJO. First, I’ve created the class in the package dto. Then I’ve added the fieldsfirstName, lastName, address, ssn and phone and id. Also, I need getters and setters for these fields. It’s good to have a constructor that uses these fields, and a DTO class should have a toString() method.

Now, I need the same corresponding Ext JS model for my Person. I just annotate this class with the CDB annotation called @JSClass to ask CDB to generate the Ext JS model.

Person Data Transfer Object

	package dto;
	import com.farata.dto2extjs.annotations.JSClass;
	import com.farata.dto2extjs.annotations.JSGeneratedId;
	public class Person {
	private Integer id;
	private String firstName;
	private String lastName;
	private String phone;
	private String ssn;
	public Person(Integer id, String firstName, String lastName, String phone,
	String ssn) {
	super(); = id;
	this.firstName = firstName;
	this.lastName = lastName; = phone;
	this.ssn = ssn;
// Getters and Setter are omitted

Next, I need to annotate the id field with the CDB annotation @JSGeneratedId. With this annotation, I’ll instruct CDB to treat this field as an auto-generated id. Let’s examine the directory of the Ext JS MVC application and take a look inside the model folder. Inside the model folder (the JavaScript section), we have the folder dto which corresponds to the Java dto package where the class resides.

Farata Systems

Figure 5. Generated from Java Class Ext JS Model

As you can see Clear Data Builder generated two files as recommended by the Generation Gap pattern, which recommends keeping the generated and handwritten code separate by putting them in different classes, linked by inheritance. Let’s open the Person model. In our case, the PersonModel.js is extended from the generated_PersonModel.js. In case we need to customize this class, we’ll do it inside thePersonModel.js, but this underscore-prefixed file will be regenerated each and every time when we change something in our model. CDB follows this pattern for all generated artifacts — Java services, Ext JS models and stores. This model contains all the fields from our Person DTO.

Now, we need to create a Java service to populate the Ext JS store with the data. Let’s create an interface PersonService in the package service. This service will return the list of persons. This interface contains one method -List<Person> getPersons().

I need to ask CDB to expose this service as a remote object, which is done by the annotation @JSService. Another annotation @JSGenetareStore will instruct CDB to generate the store. In this case, CDB will create the destination-aware store. This means that the store will know from what remote service to populate its content. All configurations of the store’s proxies will be handled by the code generator. With @JSFillMethodannotation, we will identify our main read method (remember the “R” from CRUD).

Also, it would be nice to have some sort of UI to test the service — the annotation @JSGenerateSample will help here. CDB will examine the interface PersonService, and based on these annotations will generate all Ext JS MVC artifacts (models, views, controller) with the sample application.

PersonService Interface Annotated with CDB Annotations

	public interface PersonService {
	List<Person> getPersons();

When the code generation is complete, you’ll get the implementation for the service — PersonServiceImpl. The store folder inside the application folder (WebContent\app) has the store, which is bound to the PersonModel. And my person model was generated previously. In this case, Clear Data Builder generated the store that binds to the remote service.

Farata Systems

Figure 6. Structure of Store and Model Folders

All of this intermediate translation from the JavaScript to Java and from Java to JavaScript is done by DirectJNgine, which is a server side implementation of the Ext Direct protocol.

There is one more thing you don’t want to miss — Clear Data Builder generated a UI for us! Check out the samples directory shown in Figure 7.

Farata Systems

Figure 7. Folder with Generated Samples

You can see the SampleController and SampleGridPanel inside the samples folder. CDB also generates the JavaScript application entry point — sampleApp.js. To test this application, just copy the file SampleController.js into the controller folder, SampleGridPanel.js into the view folder, and the sample application in the root of ourWebContent folder. You need to change the application entry point with sampleApp in index.html.

This is how the generated UI of the sample application looks:

Farata Systems

Figure 8. Scaffolded CRUD Application Template

Let’s return to the server side code. For services, CDB also follows the Generation Gap Pattern, and it generated stubs for the service methods. Override these methods when you’re ready to implement the CRUD functionality.

Implementation of PersonService Interface

	package service;
	import java.util.ArrayList;
	import java.util.List;
	import dto.Person;
	import service.generated.*;
	public class PersonServiceImpl extends _PersonServiceImpl { // 1
	public List<Person> getPersons() {				// 2
	List<Person> result = new ArrayList<>();	
	Integer id= 0;
	result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
	result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
	result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
	result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
	return result;		// 3
public void getPersons_doCreate(ChangeObject changeObject) {  // 4
Person dto = (Person) deserializeObject(
(Map<String, String>) changeObject.getNewVersion(),
public void getPersons_doUpdate(ChangeObject changeObject) {	// 5
// TODO Auto-generated method stub
public void getPersons_doDelete(ChangeObject changeObject) {	// 6
// TODO Auto-generated method stub
  1. We need to extend the generated class and provide the actual implementation.
  2. getPerson is our retrieve method (the R in CRUD).
  3. For this sample application, we can use java.util.ArrayList class as the in-memory server side storage of the Person objects. In real world applications, you’d use a database or other persistent storage.
  4. fillmethod+doCreate() is our create method (the C in CRUD).
  5. fillmethod+doUpdate is our update method (the U in CRUD).
  6. fillmethod+doDelete is our delete method (the D in CRUD).

Click on the Load menu, and you’ll get 4 persons from our server.

To demonstrate the rest of the CRUD methods, we’ll ask the user to insert one new row, modify three existing ones and remove two rows using the generated Web client. The object will automatically create a collection of six ChangeObject’s — one to represent a new row, three to represent the modified ones and two for the removed rows.

When the user clicks on the Sync menu, the changes will be sent to the corresponding do… remote method. When you sync(), a standard is POST-ing new, modified and deleted items to the server. When the request is complete, the server’s reply data is applied to the store, expecting that some items can be modified by the server. In the case of, instead of passing around items, we pass the delta, wrapped in the ChangeObject.

Each instance of the ChangeObject contains the following:

  1. newVersion — it’s an instance of the newly inserted or modified item. On the Java side, it’s available via getNewVersion().
  2. prevVersion — it’s an instance of the deleted old version of the modified item. On the Java side, it’s available via getPrevVersion().
  3. array of changepropertyNames — this ChangeObject represents an update operation.

The rest of ChangeObject details are described in the Clear Data Builder wiki on Github (see the Useful Links section below).

The corresponding Java implementation of ChangeObject is available on the server side, and Clear Toolkit passes ChangeObject instances to the appropriate do* method of the service class. Take a look at the getPersons_doCreate() method from the code sample above. When the server needs to read the data that arrived from the client, your Java class has to invoke the method changeObject.getNewVersion(). This method will return the JSON object that you need to deserialize into the object Person. This is done in the code sample above and looks like this:

	Person dto = (Person) deserializeObject(
	(Map<String, String>) changeObject.getNewVersion(),Person.class);

When the new version of the Person object is extracted from the ChangeObject, you can do whatever has to be done to persist it in the appropriate storage. In our example, we just print the new person information on the server side Java console. This is why we said earlier, that it may be a good idea to provide a pretty printing feature on the class Person by overriding method toString(). Similarly, when you need to do a delete, the changeObject.getPrevVersion() would give you a person to be deleted.

Part Three: Data Pagination

The pagination feature is needed in almost every enterprise web application. Often, you don’t want to bring all the data to the client at once — a page by page feed is a lot more responsive. The user can navigate back and forth between the pages using pagination UI components. To do that, we need to split our data on the server side into chunks, so we can display it when the specific page is required.

In Part Three, I’ll cover Implementing Pagination including:

  • Add the data pagination to our sample CRUD Ext JS + Java application:
    • Add the Ext.toolbar.Paging component
    • Bind both grid and pagingtoolbar to the same store
    • Use DirectOptions class to read the pagination parameters

We are going to extend our CRUD application by adding the paging toolbar component bound to the same store as the grid. The class DirectOptions will handle pagination parameters on the server side.

In Parts 1 and 2, you learned how to generate the UI from the Java back-end service and how to generate the Ext JS store and Ext JS model. In this part, you’ll learn how to add the pagination functionality to your CRUD application by asking the server to send only portions of the data. We’ll need to refactor the service code from the previous example to generate a little bit more data than the five records.

Refactored implementation of PersonService Interface

	public class PersonServiceImpl extends _PersonServiceImpl {
	public List<Person> getPersons() {
	List<Person> result = new ArrayList<>();
	for (int i=0; i<1000; i++){
	result.add(new Person(i, "Joe", "Doe", "555-55-55", "1111-11-1111"));
return result;

The Google Chrome Console shows that PersonStore was populated with one thousand records. Let’s add the pagination component using the Ext toolbarpagingcomponent, and let’s add it to the file sampleApp.js above.

Sample Application Entry

	disableCaching : false,
	enabled : true,
	paths : {
	episode_3_pagination : 'app',
	Clear : 'clear'
// Define GridPanel
var myStore = Ext.create('',{});		// 1
Ext.define('episode_3_pagination.view.SampleGridPanel', {
extend : 'Ext.grid.Panel',
store : myStore,
alias : 'widget.samplegridpanel',
autoscroll : true,
plugins : [{
ptype : 'cellediting'
dockedItems: [
	xtype: 'pagingtoolbar',		// 2
	displayInfo: true,
	dock: 'top',
	store: myStore			// 3
columns : [
{header : 'firstName', dataIndex : 'firstName', editor : {xtype : 'textfield'}, flex : 1 },
{header : 'id', dataIndex : 'id', flex : 1 },
{header : 'lastName', dataIndex : 'lastName', editor : {xtype : 'textfield'}, flex : 1 },
{header : 'phone', dataIndex : 'phone', editor : {xtype : 'textfield'}, flex : 1 },
{header : 'ssn', dataIndex : 'ssn', editor : {xtype : 'textfield'}, flex : 1 }],
tbar : [
{text : 'Load', action : 'load'},
{text : 'Add', action : 'add'},
{text : 'Remove', action : 'remove'},
{text : 'Sync', action : 'sync'}
// Launch the application
name : 'episode_3_pagination',
requires : ['Clear.override.ExtJSOverrider'],
controllers : ['SampleController'],
launch : function() {
Ext.create('Ext.container.Viewport', {
items : [{
xtype : 'samplegridpanel'
  1. Let’s manually instantiate this store — create a separate variable myStore for this store with an empty config object.
  2. Add the xtype pagingtoolbar to this component docked items property — I’d like to display the information and dock this element at the top.
  3. Now, the paging toolbar is also connected to same store.

Next, we need to fix the automatically generated controller to control loading of data on the click of the Load button.

Controller for Sample Application

	Ext.define('episode_3_pagination.controller.SampleController', {
	extend: '',
	stores: [''],
	refs: [{								// 1
	ref: 'ThePanel',
	selector: 'samplegridpanel'
init: function() {
'samplegridpanel button[action=load]': {
click: this.onLoad
onLoad: function() {
// returns instance of PersonStore
var store = this.getThePanel().getStore();		// 2
  1. We can bind the store instance to our grid panel. In the controller’s refs property, I’m referencing our simplegrid panel with ThePanel alias.
  2. In this case, I don’t need to explicitly retrieve the store instance by name. Instead, we can use getters getPanel() and getStore() automatically generated by the Ext JS framework.

When the user clicks the button next or previous, the method loadPage of the underlying store is called. Let’s examine the directprovider URL — server side router of remoting calls — and see what the direct request looks like. Open Google Chrome Developer Tools from the menu, View → Developer, refresh the Web page and go to the Network tab. You’ll see that each time the user clicks on the next or previous buttons on the pagination toolbar, the component sends directOptions as a part of the request.

Farata Systems

Figure 9. Request Payload Details

The default Ext Direct request doesn’t carry any information about page size. Clear JS, the client side extension of the Ext JS framework, adds some extra functionality to the component to pass the page start and limit values to the server side. At this point, the directOptions request property shown in Figure 9 can be extracted on the server side to get the information about the page’s boundaries. Let’s return to the code of PersonServiceImpl and add some extra code there. Right now, the pagination doesn’t work. The server sends the entire thousand records, because the server is not aware that the data has to be paginated. We’ll fix it in the code below.

Implementation of PersonService with Pagination

	package service;
	import java.util.ArrayList;
	import java.util.List;
	import clear.djn.DirectOptions;			// 1
	import dto.Person;
	import service.generated.*;
	public class PersonServiceImpl extends _PersonServiceImpl {
	public List<Person> getPersons() {
	List<Person> result = new ArrayList<>;();
	for (int i=0; i<1000; i++){
	result.add(new Person(i, "Joe", "Doe", "555-55-55", "1111-11-1111"));
// 2
int start = ((Double)DirectOptions.getOption("start")).intValue();
int limit = ((Double)DirectOptions.getOption("limit")).intValue();
limit = Math.min(start+limit, result.size() );		// 3
DirectOptions.setOption("total", result.size());	// 4
result = result.subList(start, limit);			// 5
return result;
  1. On the server side, there is a special object called DirectOptions, which comes with Clear Toolkit.
  2. We’re interested in start and in limit options (see Figure 9).
  3. Calculate the actual limit. Assign the size of the data collection to the limitvariable if it’s less than the page size (start+limit).
  4. Notify the component about the total number of elements on the server side by using DirectOptions.setOption() method with total option.
  5. Before returning the result, create a subset, an actual page of data. In this case, we need to use the method java.util.List.sublist(), which produces the view of the portion of this list between indexes specified by the start and the limitparameters.
  • As you can see from the Network tab in Figure 8, we limited the data load to 25 elements per page. Clicking on next or previous buttons will get you only a page worth of data. The Google Chrome Developers Tools Network tab shows that we are sending start and limit every time and our response contains an object with 25 elements.
  • If you’d like to repeat all of the above steps on your own, watch the screencasts where I perform all the actions described in this article.

    The source code is hosted on SourceForge as part of the Clear Toolkit Project under the MIT license.


    The development of an enterprise web application involves many steps that need to be done by the developer. But with the right set of tools, the repetitive steps can be automated. Remember the DRY principle — don’t repeat yourself. Try to do more with less effort.

    Additional Useful Links

    There are 5 responses. Add yours.


    2 years ago

    Thanks for sharing - many intriguing ideas.

    Some comments / questions:

    A few of your generated .js files are a little loose with the extra commas.  For example, the Ext.container.Viewport subclass I got in a simple test project had a trailing command after align: ‘center’.  The HelloController had a trailing comma… there were others.

    The tool puts A LOT of stuff in WEB-INF lib, some of which I don’t want and I think could contribute to longer build times.  I wouldn’t want the jta jars or jotm or the apache commons connection pool stuff.  Might be ok for tomcat depending on what you’re used to, but if you’re deploying to WebSphere or something I’m not really comfortable with these or with the framework choosing a transaction strategy for me.  At least get rid of the gson source jars!

    An example doing real database access with a persistence provider like hibernate would be useful.

    This might be more of an Ext Direct question, but I’m not at all sure from the examples how you’d get data back to the client after a create.  Case in point, the example where you create a Person sort of just stops after you see that the server got the request and you’re left staring at a screen where the new Person row still doesn’t have an id.  This example would be a lot better if you took it one step further and at least returned a ‘fake’ id so you could see it on the client.

    I like the idea of scaffolding, or at least the idea of generating .js from annotated java classes.  It seems like there’s much room for innovation here.  For example, no reason the paging toolbars had to be added by hand - there could have been some extra annotations that indicated the need for paging.  It would also be nice if the framework provided at least a simple means of paging among items already in memory.

    Interested to see where this project goes.

    Viktor Gamov

    2 years ago

    Hello firefoxSafari,

    Thanks for your feedback.

    // Trailing commas
    Thanks for pointing out. We will revise default templates for typos and unnecessary trailing commas.

    //Transaction libraries
    By default, Clear Data Builder creates project that could be run on Tomcat without any other dependencies. This is starting point for developer. Tomcat is widely adopted Java WebServer. But Tomcat itself is not full Java EE application server. Which means, some of the important APIs are missing. CDB runtime rely on standard Java Transaction API to translate client side Batch request into server side transactions. For that purpose, CDB ships with JOTM transaction manager library that enables JTA programming model in Tomcat. If you want to run application of WebSphere you need to manually remove jotm libraries. But you need to make sure that your JTA implementation registers java:comp/UserTransaction JNDI resource. Clear Toolkit not choosing a transaction strategy for you, as per Convention over Configuration, only provides a default implementation which works out of the box.

    //Direct and CRUD
    You can Java Example Project (New -> ClearDataBuilder for ExtJs Project in Eclipse). This project has extensive example of the CRUD methods. This example has answer to your question. Long story short, as I demonstrated in this article and screencasts, generated store has all required methods backed by server-side service implementation. There is nothing Direct or CDB specific. You can use store.load, store.add and etc

    We have something in out minds to add in future releases of CDB.
    Keep you eye on project page on Github!

    I hope this will help!



    2 years ago

    Hi Viktor,

    Thanks for the info.

    //Direct and CRUD
    You’re quite right - the Java Example Project did answer my question about id’s.  For the benefit of others reading this, the key for me was that I had to invoke changeObject.setNewVersion(dto) in my _doCreate methods after I had assigned the id I wanted to the dto.  It might be nice to add just this last bit to the screencast, too.

    FYI, the Java Example Project gave me several JavaScript errors using Ext 4.2.  The controller methods were looking for a method called getExampleCompanyStore, but the actual method Ext generated was getExampleCompanyStoreStore.  Brings back nightmares from jax-ws where wsgen always wanted to call my endpoints ServiceService!  After changing this, the examples worked as expected.

    //Transaction libraries
    I understand that I could remove the tx libraries for WebSphere and that it’s desirable for it to run on Tomcat out of the box.  However, it still does sound like CDB is choosing a tx strategy for me in that I have to use JTA and I have to bind things to JNDI.  Starting a project from sratch is one thing, but I’ve seen many apps use resource local tx and not mess with JTA at all.  Debatable whether this is good, but it’s the reality for many older JavaEE apps I’ve seen.  I think it would bring more value if the tx strategy was completely pluggable.  Maybe it is - haven’t spent enough time on CDB to give a judgement on it.

    Excited for future scaffolding options.  Would love to eventually see the templates that actually generate the scaffolding opened up to give users more control.  Something like grails or spring roo.

    Our reality is that we might not be able to use all pieces of CDB on all apps, especially existing ones.  IMO to reach the most people and have the most impact, it would good to decouple the Ext Direct and server side parts, the tx strategy, and the client side code generation.  For example, maybe because of constraints on a legacy app, someone can’t use Ext Direct but they still get value from annotating Java classes to generate Ext model and sample grid, albeit not with not as much functionality.  I realize this might not fall into the overall goals for the project, though.

    I’ll keep playing around and check out the rest of the wiki pages - glad Java to Ext scaffolding options are starting to emerge.

    Viktor Gamov

    2 years ago

    Hi firefoxSafari,

    // Controller getters
    Yes, it’s known issue with ExtJS 4.2 and it will be fixed in next release of CDB.
    As for now, you can grab the code from Github and place it in your project. If you have other issues, feel free to report to the issue tracker [1].

    // Transactional
    Server-side component clear.transaction.djn.BatchGateway ( uses JTA to perform transactional handling of batch members that sent by BatchManager (see, sync() method) client-side component. If you don’t want to use JTA stuff, you need to provide your own implementation with signature described (In find annotated @DirectMethod execute method). If you have some particular use case in mind, please, fill the bug in the issue tracker on the Github [1], and will try to help you with it.

    The ExtJS Models generator can be used as a standalone utility. Here is an example how it can be used from command line ($JAVA_HOME/bin should be in the PATH).
    Also you can customize a service code generation even today. The templates (CDB uses XSL for the templates) are fully customizable. Please, look inside cdb_build folder of a generated project.
    FYI, Clear Data Builder does not wipe out the generated code, it only replaces the older source files with the newer versions. Consequently, if you rename your Java classes, it is your responsibility to delete the generated source files related to the old class. Long story short, you can throw away a generator part any time.




    2 years ago

    Hi Viktor,

    Thanks for the excellent responses.  It sounds like the toolkit has been very well thought out.

    Just a suggestion that some of these points would be good to have on the wiki wink

    Nice work!

    (note: third time I’ve tried to respond so apologies if there’s someday a flurry of dup comments).

    Comments are Gravatar enabled. Your email address will not be shown.

    Commenting is not available in this channel entry.