This section details the development process with Kiss. The details provided will be for IntelliJ but can be adapted to other IDEs. 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.
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.
./view-log
(not needed on Windows)
This is where back-end messages appear. This command is not needed under Windows.
./bld develop
(bld develop
on Windows)
This builds the system and runs the back-end and front-end servers.
This will allow you to debug the back-end.
This is where you view and interact with your application.
This is where you debug the front-end.
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 will take effect immediately.
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
directory for further
information.
The back-end works differently in development and production environments. Although in both environments back-end and front-end changes take effect immediately, the 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
.
There are two different methods of running the back-end REST server as follows.
Running the IDE back-end requires the following:
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 breakpoints) as if it 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.
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:
./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.
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:
Kiss
back-end receives the request.
outjson
object is filled in by the web service that is to be returned to the front-end.
outjson
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.
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", "dataValue")
See Authentication
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.
Due to the easy and natural connection between Java and many other JVM languages, interfaces to those languages are 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.
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 echoes
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 be 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.
For security reasons, web servers prevent web services from an application that doesn’t come from the same origin. This is known as Cross-Origin Resource Sharing or CORS. Kiss fully supports this security standard.
Kiss automatically enables full CORS protection in production environments and allows CORS in the development environment.
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:
./bld UnitTest
This creates the work/KissUnitTest.jar
file which contains
the entire Kiss system and unit tests.
All tests can be run by executing 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.
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 you 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.
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.
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 selecting 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.
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.
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.
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 are 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