4 Developing

This section details the development process with Kiss. The details provided will be for IntelliJ but can be adapted to other IDE’s. The use of an IDE is tremendously beneficial because of the graphical debugging and intelligent code completion capabilities.

A good development environment includes two separate servers running on two different ports. One serves the back-end REST services, and the other serves the front-end HTML, JavaScript, and CSS files. This arrangement allows both front-end and back-end development without any compiles, server reboots, file copies, or deployments. Back-end and front-end files can be edited and saved. Their changes take effect immediately.

Of course, in a production environment, only a single server would be utilized and front-end and back-end changes take effect immediately there too.

4.1 Overview

The following details the normal steps to boot up a development environment. Once this environment is set up, it may remain active for the whole day. There is rarely any reason to re-build or re-boot the development environment.

Note that all of the command-prompt commands are executed from the root of your application.

  1. In a command-prompt, type: ./view-log (not needed on Windows)

    This is where back-end messages appear. This command is not needed under Windows.

  2. In a second command-prompt, type: ./bld develop (bld develop on Windows)

    This builds the system and runs the back-end and front-end servers.

  3. In the IDE, attach to the Java process at port 9000.

    This will allow you to debug the back-end.

  4. From your browser, go to http://localhost:8000

    This is where you view and interact with your application.

  5. Open the Developer tools from within the browser.

    This is where you debug the front-end.

  6. Be sure to disable network caching on the browser. (Otherwise, changes you make to the front-end will not immediately appear in the browser.)

At this point, development, testing, and debugging can occur unabated. There should be no need to rebuild or bring anything down.

Front-end changes will appear as soon as you re-load the page on your browser. Back-end changes with take effect immediately.

4.1.1 IDE

While development with Kiss does not require an IDE, most developers utilize an IDE (Integrated Development Environment). Kiss includes an effort to assist with IDE integration (such as an ant interface to our build system).

See the files under the manual/IDE-Setup director for further information.

4.2 Back-end Development

The back-end works differently in development and production environments. Although in both environments back-end and front-end changes take effect immediately, setup of the production environment copies all files into the production environment, whereas in a development environment the source and production code are split. In order to facilitate rapid and easy development, it is important that source files be used rather than the production copies during the development process.

The system automatically detects the location of the application source in most configurations. However, this may be explicitly set via a system environment variable (KISS_ROOT). The value of this environment variable should be the absolute path of the root of the application source code. The directory it indicates should have a sub-directory named src/main/backend.

4.2.1 REST Server

There are two different methods of running the back-end REST server as follows.

4.2.1.1 IDE

Running of the IDE back-end requires the following:

  1. The IDE is completely configured.
  2. The system was build with the IDE

Typically, the IDE manages a tomcat instance and serves up the core back-end code serving the REST services. That code detects that it is running under an IDE and re-routes all back-end application files back to the source directories.

Although back-end files are edited in source form and run in compiled form, back-end code can be debugged (including break-points) as if they were compiled before the system was booted.

Once the back-end server is up, application files changed under the src/main/backend directory will take effect immediately.

4.2.1.2 BLD

Utilizing the included Kiss build system (bld) the many steps required to install and configure tomcat and the IDE are unnecessary. The whole process (for the back-end portion) can be done as follows:

  1. From any stage (including having just downloaded the Kiss system) type the following: ./bld develop

    Note: Remember that all commands that start with ./ would drop the ./ under Windows.

At this point, the back-end will be running. From within your IDE you can attach to the process at port 9000 to debug the back-end (including breakpoints, etc.)

Remember, however, that you won’t be able to use or debug the application until the front-end server is started too.

4.2.2 Application Code

All communications between the front-end and back-end occur over REST services you define. Each REST service exists in its own file or class. Web methods are methods within those classes.

As architected, directories under src/main/backend represent the application’s REST services. Each class / file under that directory represents a web service. The name of the class is the name of the web service.

Instance methods within the web service class represent REST methods for that web service. Each web method is passed four arguments as follows:

JSONObject injson

This represents the data that came from the front-end.

JSONObject outjson

This represents the data being returned to the front-end. It is pre-initialized with an empty JSONObject.

Connection db

This is a pre-opened connection to the defined database (defined in backend/KissInit.groovy)

MainServlet servlet

This is a rarely used servlet context argument.

Basically what happens is:

  1. The front-end makes a REST service call.
  2. The Kiss back-end receives the request.
  3. The user gets authenticated.
  4. A new database connection is formed, and a new database transaction is started.
  5. The requested web service is identified (and loaded and compiled if needed).
  6. The outjson object that is filled in by the web service that is to be returned to the front-end.
  7. Upon completion of the REST service, Kiss commits the transaction, closes the database connection, and returns outjson to the front-end.
  8. If, however, the REST service threw an exception, Kiss rolls back the transaction, closes the database, and sends an error return to the front-end.

Additional class and instance methods, that are not web methods, may be defined and used within web service classes.

Of course during this process, Kiss handles many possible error conditions.

4.2.3 Cached User Data

During the login process, user-specific data may be cached. This often occurs in the login Groovy method of the Login application-specific class.

Every web service has access to this data via the following method:

        servlet.getUserData().getUserData("dataName")
        servlet.getUserData().putUserData("dataName", "datValue")

See Authentication

4.2.4 Programming Languages

At this point, Kiss supports the development of back-end REST services in the Java, Groovy, or Common Lisp languages. Groovy was added first because it was easy, worked with the IDE well, and did all that was needed. (See the document GroovyOverview included with KISS.) Java was added simply due to its natural integration with the rest of the system.

With Kiss, different web services can be written in different languages. You are not forced to use one or the other.

Common Lisp (ABCL) was added due to this author’s love of that language. Unlike Groovy and Java, Lisp has an impedance mismatch with the core Kiss system that is written in Java. For example, in Java, one can have two methods with the same name in the same class that differ only by their argument types. This is not part of the Common Lisp language. Also, the foreign function interface in Lisp requires some Lisp code to make the connection clear. Due to this connection code having to run, the Lisp interface is very slow on the first call. It is, however, reasonably fast on all subsequent calls. The code that interfaces Java to Lisp is under the src/main/core/org/kissweb/lisp directory.

Do to the easy and natural connection between Java and many other JVM languages, interfaces to those languages is very easy. It is anticipated that support for many of these other languages (such as Scala, Clojure, JRuby, Jython, and Kotlin) will likely follow, especially if there are requests.

4.2.5 Cron

Kiss has the ability to run any number of commands at specified intervals. For example, you could run a process every hour and another process every Tuesday at 3 PM, etc. This facility echos the standard Unix or Linux cron facility.

The file that determines what gets run and when is
src/main/backend/CronTasks/crontab. All tasks must be in the Groovy language and exist in the src/main/backend/CronTasks directory.

All contents of the src/main/backend/CronTasks can be changed on a running system. The change will get noticed and take effect. There is no need to restart the system.

Look at the files in the src/main/backend/CronTasks directory for samples and further documentation.

4.2.6 CORS

For security reasons, web servers prevent web services from an application that didn’t come from the same application. This is known as Cross-Origin Resource Sharing or CORS. Kiss fully supports this security standard.

Kiss automatically enables full CORS protection on production environments and allows CORS in the development environment.

4.2.7 Unit Tests

Kiss supports jUnit unit tests. The tests are located under the src/test directory. The directory hierarchy under the src/test should mirror that of the src/main directory.

Unit tests may be run as follows:

  1. Add or change unit tests or code to be tested.
  2. Build KissUnitTest.jar by executing:
        ./bld UnitTest
    

    This creates the work/KissUnitTest.jar file which contains the entire Kiss system and unit tests.

All tests can be run by running the following command:

java -jar work/KissUnitTest.jar -cp work/KissUnitTest.jar 
                                                  --scan-class-path

Alternatively, a single test can be run as follows:

java -jar work/KissUnitTest.jar --select-class org.kissweb.IniFileTest

where org.kissweb.IniFileTest is the full path to the desired test.

4.3 Front-end Development

A separate server is used so that development files will be served rather than the front-end that was present when the back-end server was started. This is the same whether your are using the IDE or bld back-end server modes.

Once the back-end and front-end servers are running, the front-end can be debugged through your browser debugger (F12 on Chrome).

In order to make this work, there are two steps that need to be followed.

  1. The front-end needs to know where the back-end is located. This is controlled in the file src/main/frontend/index.js. That file contains a line that looks as follows:
        Server.setURL('http://localhost:8080');
    

    As shipped, that setting should be good in most cases. Adjust as needed.

  2. A server needs to be running to serve the front-end code. The Kiss system comes with a simple server that performs this function. It is in a file named SimpleWebServer.jar on the root of the Kiss system. From the root of the Kiss system, run the following command to run the front-end server:
       ./serve
    

    or on Windows:

       serve.cmd
    

(Source code to this simple server is available at https://github.com/blakemcbride/SimpleWebServer)

Once the front-end and back-end servers are up, you can access the development environment through your browser at http://localhost:8000

If you disable the browser cache through the browser developer console settings, changes you make to the front-end will appear by just reloading the page. On Chrome, for example, the browser cache can be turned off by going into the page debugger (F12), then settings, and then select Disable cache (while DevTools is open)

You can now develop the front-end portion of your application by editing files under the src/main/frontend directory.

4.3.1 Mobile Interface

It is often necessary to support mobile devices. Although many applications support mobile applications through pages that use responsive design, it is often the case that the pages are so different between various platforms that the use of whole new pages is simpler and more effective – especially for complex screens.

Although Kiss has always supported responsive design, Kiss also supports the ability to have different pages for different platforms. If you look at src/main/frontend/index.js you will see how Kiss handles this. Basically Kiss detects the platform and loads different pages based on the platform.

4.4 Reports And Exports

Creating reports and exports requires both front-end and back-end components. The back-end usually creates the file to be sent to the front-end. It then returns a path that the front-end can use to download the file.

Kiss provides the infrastructure needed to support this facility. Kiss also manages and cleans up report files that are no longer needed.

In terms of producing reports, Kiss leverages the facilities provided by the common groff/tbl/mm utilities publicly available. These facilities automatically handle paging, titles, page numbering, tables, and overall formatting of your reports. See https://www.gnu.org/software/groff

In terms of producing CSV export files, see the back-end DelimitedFileWriter class.

When files are produced by the back-end, they are sent to the front-end by just providing the URL to the file. At that point, the front-end Utils.showReport takes the URL returned by the back-end and downloads the file.

4.5 Authentication

Kiss has built-in authentication. However, each application has its own method of storing and validating users. Additionally, each application may have its own user-specific data it may want to retain between web service calls. Kiss has a generic and easy way of handling these needs.

Application-specific user login and data is handled by the Groovy file located in the backend directory named Login.groovy. That file must have two methods; login and checkLogin. See that file for more details.

See Cached User Data