Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Tuesday, September 03, 2019

Formatting NotesDatetime as Java SimpleDateFormat

Recently I had to made proper formatting of NotesDateTime object (using LotusScript) with respect to different locale. I had written a cover in LS2J for Java SimpleDateFormat class that works independently (without Java library), so copy/paste and go on.

Here is an example how it works
Dim jdtr As New jDateTimeRich
Dim dt As New NotesDateTime("15-10-2017 10:20:30")

MsgBox jdtr.SimpleDateFormat(dt, "dd-MM-yyyy", "", "") ' "15-10-2017"
MsgBox jdtr.SimpleDateFormat(dt, "d-MMM-yy", "ru", "RU") ' "15-окт-17"
MsgBox jdtr.SimpleDateFormat(dt, "EEEEE MMMMM yyyy HH:mm:ss.SSSZ", "da", "DK") ' "søndag oktober 2017 11:20:30.000+0200")

The beautiful part of it - is translation of months and days according to Locale.
I have uploaded source/class on github. Feel free to re-use it: jDatetimeRich-LS and report issues of course.

Tuesday, July 17, 2018

Domino with Java 6 and TSL 1.2

Recently I have faced an issue where one of our provider changed SSL and they disabled supporting of TLS 1.0 (as far as I understand it's non secure ourdays) and TLS 1.2 should be used instead. As a result our java agents (which used HttpsURLConnection) could not connect anymore to provider.

Error message looked like this:
Caused by: Access denied ( setHostnameVerifier)
I have found 2 possible solutions:

Enable TLS 1.2 on Domino (applicable only for 9.0.1 FP3 IF2 and higher)

The Domino JVM is based on Java 1.6 and default settings configured in a way to use TLS 1.0. Luckily our Domino servers had version 9.0.1 FP4 (and TSL 1.2 support has been added since FP3 IF2). So our version was capable to work with 1.2 (in theory) but it took some time to make it work.

In order to configure Domino JVM to use TLS 1.2 you need to:
  1. Create JVM settings file, f.x. C:\Domino\jvmOptions.ini
  2. Add parameter in jvmOptions.ini
  3. Add path to jvmOptions.ini file in notes.ini
After you added settings don't forget to restart Domino server. Keep in mind that setting is global meaning all agents that will start to use TLS1.2 therefore it is definitely worth to verify everything before and after this fix.

Java library solution

If that is not a way you can go with (f.x. Domino has lower version or something won'f work if you switch to TLS 1.2) then it's still possible to make custom Java Library that will make it possible, see link: How to use TLS 1.2 in Java 6.

It worked for me as well, but it requires to give permission in java policy on Domino server.

Wednesday, December 21, 2016

Hello World on Play Framework 2.5 on OSX

Today we are going to make Hello World project based on Play Framework 2.5 on OS X

I'm getting back to Play Framework again and I'm going to build simple start project.

1. Checking if Java is installed

Make sure you have java installed.

java -version

If java is installed you will see message like that:

java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

2. Installing Typesafe activator (current version is 1.3.12)

brew install typesafe-activator

3. Let's create a new project

activator new hello-world

Activator will ask you what template you want to use for new project? (I used play-java).

  1) minimal-akka-java-seed
  2) minimal-akka-scala-seed
  3) minimal-java
  4) minimal-scala
  5) play-java
  6) play-scala

That will create a java project for us

Now let's run it. Go into newly create project and run activator

activator run

That will run our project and up server as well. You can access project by localhost:9000

Tuesday, March 22, 2016

Use equal for string literal, rather than for an object

When you wanna compare String object with string literal, we often disregard what we compare with what, however there is one and safe way to do it.

It's much better to use equals() and equalsIgnoreCase() for a string literal, instead of Object, because it helps to avoid possible NullPointerException.

Here is an example:
 String a = null;  
 System.out.print("123".equals(a));     // false  
 System.out.print(a.equals("123"));     // java.lang.NullPointerException

Friday, January 08, 2016

Typical mistakes with String in Java

Just few typical mistakes developers do when dealing with Strings. It's common stuff and everybody knows that, but for some reasons I still find such things (even written by myself :-)).

1. Checking empty string

In old days (version 1.5 and lower) we used String.equal(""), but 1.6 brought us String.IsEmpty which is better and faster.
 // wrong/slow  
 if (name.equals("")) {  
 // correct/fast
 if (name.isEmpty()) {

2. Concatenation

Method String.concat creates new String object, it's OK to use it when you do operation only once, otherwise use operator + += operators (see below why).
 String s = "Hello ".concat("new").concat(" world!"); // "Hello new world!"  
Using operators + and +=, they do not use String.concat method but StringBuilder and it's important to know what it means to us.
 String s = "Hello " + "new" + " world!"; // "Hello new world!"
What actually happens when you use + operator is StringBuilder used:
 String s = new StringBuilder().append("Hello ").append("new").append(" world!").toString(); // "Hello new world!"
So conclusion - it's ok to use concat if you do one time operation, for any other situation I would recommend to use + or +=.

3. String Formatting

Very often in order to format string people either concatenate the string to achieve result or do replace or invent something else. I do it as well sometimes (what a shame!). Instead we should use String.format method to do that.
 int n = 10;  
 // wrong  
 String s = "I have " + Integer.toString(10) + " books";  
 // wrong  
 String s = "I have #num books".replace("#num", Integer.toString(10));  
 // correct  
 Strig s = String.format("I have %d books", n);  

I would be glad to hear other typical mistakes we do with String object! So please share your experience.

Thursday, January 07, 2016

SOAP and passing session

Here is an example how to pass session using SOAP envelope approach. I was starlight with it for some time.

That is why people use REST our days :) and not SOAP approach.

   // Create SOAP Connection  
   SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();  
   SOAPConnection soapConnection = soapConnectionFactory.createConnection();  
   // connect to webserivce
   SOAPMessage soapResponse =, password), url);

   // read cookie from response and use it when send another requests
   MimeHeaders session = soapResponse.getMimeHeaders(); 
   String sesisonCookie = session.getHeader("Set-Cookie")[0];

   SOAPMessage soapResponse2 =, url);

Here is how we add cookie to soap request

   SOAPBody soapBody = envelope.getBody();
   SOAPElement soapBodyElem = soapBody.addChildElement("Customer_GetAll", "m");
   soapMessage.getMimeHeaders().addHeader("Cookie", sesisonCookie);

Wednesday, January 06, 2016

Java web-consumer in Domino and cookie session

Recently I've faced with few mistake that drain hours from me. I had to make integration with web-serivce. I imported WSDL file and got java classes generated, than I according to documentation I checked connect method with credentials...
Error connecting to 'endpoint' on port '443', SSL invalid certificate, may need to cross-certify
Spend some time and found very detailed answer on stackoverflow: Create cross certificate for Domino Java agent?

Tried connect method again - it worked! Gonna be easy task now (I thought). However nothing else except connect method worked. All other method of consumer either did nothing or returned null to me. I was confused, spend few hours and than contacted web-service provider, they were not familiar with Java and provided me example in PHP that worked as expected.

My issue was I had to set SESSION_MAINTAIN_PROPERTY to true for my proxy object.

 SecretServiceLocator service = new SecretServiceLocator();  
 SecretPortType port = service.getSecretPort();  
 ((javax.xml.rpc.Stub)port)._setProperty(javax.xml.rpc.Stub.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE);  


Standard property: This boolean property is used by a service client to indicate whether or not it wants to participate in a session with a service endpoint. If this property is set to true, the service client indicates that it wants the session to be maintained. If set to false, the session is not maintained. The default value for this property is false.
Once I set session maintain to true - everything started to work.

Monday, January 04, 2016

Format datetime object in Lotus Script

Sometimes datetime output become tricky in Lotus Notes.

F.x. imagine you have code like this and you have german or any another locale on user's PC.
 Set dt = New NotesDateTime("")  
 Call dt.SetNow  
 msgbox Format$(dt.LSLocalTime, "dddd, dd. MMMM yyyy")  

Out would be
Tuesday, 22. December 2015

But what if you want output in german i.e.?
22. Dezember 2015

In such case you may want to use LS2J approach to display it properly to user

Below you will find a solution that either allow to set locale or use default locale.
 Option Public  
 Option Declare  
 UseLSX "*javacon"  
 Sub Initialize   
  On Error GoTo errhandler  
  Dim jSession As New JavaSession  
  Dim jCalendarClass As Javaclass, jLocaleClass As JavaClass, jSimpleDateFormatClass As JavaClass
  Dim jCalendar As Javaobject, jLocale As Javaobject, jSDF As JavaObject, jDate As Javaobject  
  Dim jError As JavaError  
  Dim dt As New NotesDateTime("")  
  Call dt.SetNow  
  'in order to initiate date - we have to use Calendar object  
  Set jCalendarClass = jSession.GetClass("java.util.Calendar")  
  Set jCalendar = jCalendarClass.getInstance()  
  Call jCalendar.set(Year(dt.DateOnly), month(dt.DateOnly) - 1, day(dt.DateOnly))  
  'initialize date object  
  Set jDate = jCalendar.getTime()  
  'create locale (here we specify langauge/country code)   
  Set jLocaleClass = jSession.GetClass("java.util.Locale")  
  Set jLocale = jLocaleClass.CreateObject("(Ljava/lang/String;Ljava/lang/String;)V", "de", "DE")  
  'also you can use local settings, if you need that - enable line below  
  'Set jLocale = jLocaleClass.getDefault()  
  'output format  
  Set jSimpleDateFormatClass = jSession.GetClass("java.text.SimpleDateFormat")  
  Set jSDF = jSimpleDateFormatClass.CreateObject("(Ljava/lang/String;Ljava/util/Locale;)V", "dd. MMMM yyyy", jLocale)  
  MsgBox jSDF.format(jDate)  
  Exit Sub  
  Set jError = jSession.GetLastJavaError()  
  MsgBox "JavaError was " & jError.errorMsg  
  Resume done  
 End Sub  

Related topics:
Locale settings for date and time in IBM Domino and Notes

Wednesday, October 14, 2015

Setup Play Framework and TypeSafe on centOS

I'm going to setup simple project based on Play Framework together with Cassandra on two centOS servers.

I'm going to do 3 steps during that process:
  1. Install Java
  2. Install Typesafe activator
  3. Create test project.

Installing Java

//1. go to opt folder
cd /opt

//2. download java
wget --no-cookies --no-check-certificate --header "Cookie:; oraclelicense=accept-securebackup-cookie" ""

//3. extract java archive
tar xzf jdk-8u60-linux-x64.tar.gz

//4. installing java
cd /opt/jdk1.8.0_60/
alternatives --install /usr/bin/java java /opt/jdk1.8.0_60/bin/java 2
alternatives --config java

//5. recommended options: setup javac and jar
alternatives --install /usr/bin/jar jar /opt/jdk1.8.0_60/bin/jar 2
alternatives --install /usr/bin/javac javac /opt/jdk1.8.0_60/bin/javac 2
alternatives --set jar /opt/jdk1.8.0_60/bin/jar
alternatives --set javac /opt/jdk1.8.0_60/bin/javac

//6. setup variables so we can access java from everywhere
export JAVA_HOME=/opt/jdk1.8.0_60
export JRE_HOME=/opt/jdk1.8.0_60/jre
export PATH=$PATH:/opt/jdk1.8.0_60/bin:/opt/jdk1.8.0_60/jre/bin

//7. checking java version
java -version

//8. delete java archive
rm jdk-8u60-linux-x64.tar.gz

Installing Play Framework / TypeSafe

Example is about current version, which is 1.3.6
//1. go to tmp folder and download typesafe activator
cd /tmp

//2. unzip and move to opt folder
mv activator-dist-1.3.6 /opt

//3. delete zip file, we do not need it anymore

//4. create soft symbolic link from /opt/activator-dist-1.3.6/activator to /usr/local/sbin/activator
ln -s /opt/activator-dist-1.3.6/activator /usr/local/sbin/activator

//5. set variables so we can use activator from everywhere
export PATH=/usr/local/sbin/activator:$PATH

Create helloworld project

Time to create our first project. Play Framework provides many templates, we are going to use play-java (it has already web interface and some code, so we can discover it).
//1. create folder www in /var (we are going to keep projects there).
cd /var
mkdir www
cd www

//2. have a look on current templates
activator list-templates

//3. create a new project based on play-java template
activator new helloworld play-java

//4. go into newly created project and run it
cd helloworld
activator run

If activator run properly, you should see something like this:

Now you are ready to open project in browser. Type and boooom, we have it ready!

I'm going to play with centOS little bit more (before I start to look on code). I already have some minor issues I want to optimise.

Saturday, July 04, 2015

Transformation of String into Date respecting Locale

Let's say you need to parse a string into date and it is localized string (f.x. name of month on local language). In past I would definitely define an array with months and then parse a String to get a number of my month and then build a Date object. In Java it's pretty simple (almost 1 line of code).

Locale approach

package parser;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class parser {

 public static void main(String[] args) throws ParseException {
  Locale locale = new Locale("ru");
  Date date = convertStringToDate("19 Сентября 2004", "d MMMM yyyy", locale);
  System.out.println(date); // Sun Sep 19 00:00:00 CEST 2004
 public static java.util.Date convertStringToDate(String dateString, String format, Locale locale) throws ParseException {
  return new SimpleDateFormat("d MMMM yyyy", locale).parse(dateString);
Alternatively, if you need to define months yourself use DateFormatSymbols

Define symbols in DateFormatSymbols

package parser;

import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;

public class parser {

 public static void main(String[] args) throws ParseException {
  String months[] = {"Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"};
  DateFormatSymbols dfs = new DateFormatSymbols();
  SimpleDateFormat sdf = new SimpleDateFormat("d MMMM yyyy");
  System.out.print(sdf.parse("19 Сентября 2004")); // Sun Sep 19 00:00:00 CEST 2004

Monday, January 05, 2015

Find Orphan pages on website

You have a website and want to be sure that there are no Orphan pages? Not sure how to develop it? If so - you found a right place to go :), let's talk about most important steps.
I assume you have a list of all pages you want to verify (otherwise - it will be your first task)

Here is a logic/snippets
  1. We need functionality that can extract HTML from a web page. Later we will scan it and get internal links.
    private String getPageContent(String pageurl) throws Exception {
       StringBuffer buf = new StringBuffer();
       URL url = new URL(pageurl);
       InputStream is = url.openConnection().getInputStream();
       BufferedReader reader = new BufferedReader( new InputStreamReader( is )  );
       String line = null;
       while( ( line = reader.readLine() ) != null )  {
       return buf.toString();
  2. Make a logic that can deal with DOM. I use jsoup to manipulate with HTML and I really recommend it (easy and fast). The method below select all links that begin with baseurl (it's domain of your website), in that way we can cut all external links and get only internal links.
    private List<string> getAllInernalLinks(String html, String baseurl) throws Exception {
       List<string> res = new ArrayList<string>();
       String select = "a[href^="+baseurl+"]";
       org.jsoup.nodes.Document dom = Jsoup.parse(html);
       Elements links =;
       for (Element link : links) {
          String src = link.attr("href");
       return res;
  3. Now we must build a List with all internal links from all pages on your website.
    String List<string> alllinks = getAllInernalLinks(html_from_all_pages, baseurl);
  4. We need to make sure that pageurl can be found in alllinks more then in pagelinks (to avoid case when page has link to itself).
    private boolean isOrphan(List<string> pagelinks, List<string> alllinks, String url) throws Exception {
       if (Collections.frequency(alllinks, url) > Collections.frequency(pagelinks, url)) {
          return false;
       return true;

Monday, September 08, 2014

Issues when importing WSDL files into Web Service Consumer

Recently I faced up with WSDL which I couldn't import into Web Service Consumer. Our consumer worked well from last 5 years but it is a long period and during that time our Service Provider was updated a lot so we decided to update our Consumer as well. Guess everything went fine?
No WSDL was returned from the URL
I simply created new Consumer in Domino Designer, set URL to our WSDL, picked Java and clicked OK. Oops...
Domino Designer
No WSDL was returned from the URL:
The requested operation failed: no import files
Wow, thought I :) let's try to import WSDL as Lotus Script then (just to see if it is not related to Java)
IBM Domino Designer
The requested operation failed: no import files
Name too long
Hey, what? This WSDL is used by many another applications without any issues, what is going on!? I downloaded WSDL as file to my local PC and tried to import it as Lotus Script again. This time it went fine (except issues with Name too long). Well, great news anyway, at least everything works when WSDL is a local file.

The Web Service implementation code generated from the provided WSDL could not be compiled, so no design element was created
Ok, it worked for Lotus Script, let's set now Java...
IBM Domino Designer
The Web Service implementation code generated from the provided WSDL could not be compiled, so no design element was created.  Please correct the WSDL and try again.  The errors are located in the following file:: C:\Users\dpa\AppData\Local\Temp\notes90C43B\47238811.err
OK, it's time to blame Designer and IBM! Why it is so difficult just to import WSDL? All another application that use WSDL from our server did not have such issues. It's just not fair :). Found a file with error and quite typical line: java.lang.OutOfMemoryError: Java heap space. I knew what to do, I increased HTTPJVMMaxHeapSize and JavaMaxHeapSize to 512M, restarted Designer/Notes and tried again. Worked well! I restored original values to HTTPJVMMaxHeapSize and JavaMaxHeapSize after that.
The system is out of resources.
Consult the following stack trace for details.
java.lang.OutOfMemoryError: Java heap space
at lotus.notes.internal.IDEHelper.compile(Unknown Source)
Simple thing however it costed few hours for me. Hope it will save some time for other people.

Monday, April 28, 2014

Disabling certificate validation in Java

In case you need to disable validation of certificate here is Java snippet.
 public static void disableCertificateValidation() {  
  // Create a trust manager that does not validate certificate chains  
  TrustManager[] trustAllCerts = new TrustManager[] {   
  new X509TrustManager() {  
   public X509Certificate[] getAcceptedIssuers() {   
   return new X509Certificate[0];   
   public void checkClientTrusted(X509Certificate[] certs, String authType) {}  
   public void checkServerTrusted(X509Certificate[] certs, String authType) {}  
  // Ignore differences between given hostname and certificate hostname  
  HostnameVerifier hv = new HostnameVerifier() {  
  public boolean verify(String hostname, SSLSession session) { return true; }  
  // Install the all-trusting trust manager  
  try {  
  SSLContext sc = SSLContext.getInstance("SSL");  
  sc.init(null, trustAllCerts, new SecureRandom());  
  } catch (Exception e) {}  
I took code from here: Java client certificates over HTTPS/SSL

Related topics:
IBM Domino Java: No trusted certificate found. Fail?
Domino and No trusted certificate found
Disabling certificate validation in Java

Tuesday, January 28, 2014

Domino and No trusted certificate found

We have few agents that communicate with other systems via and today at 13:00 we got such answer from Domino when we tried to set connection with external system. That was a huge problem for us since it affect our business. No trusted certificate found  
It took some time to fix it, but here is a solution


A Java application running on a Domino server connecting over SSL to another server may require having the SSL certificate authority of the other server imported into its JVM.


When a Java application running on a Domino server connects over SSL to another server, but does not have that server's trusted root certificates, an error may occur. One example of such an error is: HTTP JVM: No trusted certificate found.


The trusted root certificates that signed the remote server's SSL certificate must be also be trusted by the Domino server's JVM if a Java application is making an SSL connection.

Resolving the problem

To add the trusted root certificates to a Domino server JVM follow these steps:

A. Obtain the Certificate to be Imported

Each browser displays certificates in different ways, but they are usually quite similar. On the browser's URL bar, there is usually a zone that you can click on to display SSL certificate information. For example, you may see a padlock in the status bar, and clicking on the padlock opens the certificate information. Once the certificate information is open, click on the "Certification Path" informatino. There normally will be a way to export each of the signing certificates (trusted roots). Export the certifiers in the "Base-64 encoded X.509 (.CER)" format. The exported file in this format will be an ASCII text file that has "BEGIN CERTIFICATE" and "END CERTIFICATE" lines at the top and bottom. Once you have exported the certificates that signed the remote server's SSL certificate you can then import them into the JVM.

B. Import the SSL certifier into the JVM.

If Domino is on a UNIX server, perform these steps on a Windows workstation, and then move the cacerts to the server after the import is completed.
Import the SSL Certificate into the JVM using these steps:
  • Open a command line and change directory to C:\Lotus\Domino\jvm\bin.
  • Run the batch file "IKEYMAN.exe" (a Java application will load).
  • Click "Key Database File" then "Open".
  • Browse to C:\Lotus\Domino\jvm\lib\security\cacerts. Note, you will have to view "All Files" to locate cacerts.
  • Supply the default password of "changeit". Note, consult your administrator if you receive an error pertaining to the password.
  • Select "Signer Certificates" in the drop-down menu.
  • Click "Add"
  • Select "Browse" and locate the .CER file you copied.
  • Click "OK" and enter a descriptive label.
  • On the Domino console issue the command "restart task http".
Original link I found on IBM Importing an SSL Certificate Authority into the JVM

Related topics:
IBM Domino Java: No trusted certificate found. Fail?
Domino and No trusted certificate found
Disabling certificate validation in Java

Thursday, October 03, 2013

IBM Designer Java Console effect?

I've faced up with interesting problems. I'm doing integration between MailChimp and Domino application. MailChimp service has very good API so it was not huge problem to push/poll data to/from it and we already implemented solution based on Java. The fun started when I tried to do LS2J part. My first request to java method came up with this dialog
That error does not happen if I enable Java Console in IBM Domino Designer. When Console is up - everything works perfect, otherwise this error:
LS2J Error: Threw java.lang.SecurityException: not allowed to access members in class interface java.util.Map
I can't explain how Java Console affect my security level, however definitely it does. I think it possibly grant users with more access when it is running and maybe there is an explanation why. Does anybody of you can explain that?

Thursday, August 08, 2013

Java as backend for web applications based on Domino

Is it enough to use only Java?

Yes. Our newly created applications have been written only for web and we did all back-end with Java only (the only exclusions are selection for Views). No, we do not miss @Formula, Lotus Script or SSJS, we simply do not need those languages in our daily work. Java is better than LS/SSJS for us. You can develop much better/faster using Java and get all candies: open sources, forums, stackoverflow or even shift at some point to Java completely if it has sense for you. However, if you read my main posts I mentioned that we still had some problems while work with Java, Solution isn't really perfect and let me explain all those weakness we have right now.
  • Domino has 2 Java runtimes (huge pain for us): one is for xPages and another one for Java Libraries+Agents. Java Libraries can be reuse in xPages and back JAVA/JAR are not accessible from Libraies/Agents. Our Java libraries are core for xPages and it means we have to build JAR from them and include them for xPages. It takes time and we really do not like that, it simply looks wrong. The solution is to put JAR to Domino OS, however we are limited with access to Domino's OS. Due to that fact we have one serious disadvantage - our JAR files that we attached to Libraries and Agents have to be extracted and loaded to memory each time we run agents.
  • We are forced to use IBM Designer (and few of us would like to work in different IDE). As I mentioned we work via GitHub and it takes some time to build project (developer -> github -> jenkins -> domino). That's not a problem for FE, as they can do their tasks locally and after all just commit changes. BE part is located on Server so if we work without IBM Designer we have to wait 1-2 mins till changes come to it and only then we can do our tests. That's sad.

Does it mean @formula, Lotus Script, SSJS are not required to know?

Those languages are still important part of our 'old applications' and it will take years to completely re-write them to web and there should be a sense to do that, as it is time/money, @formula language is still only 1 way to make selection in Notes Views.

  • open source;
  • problems resolving (forums, community);
  • more abilities;
  • in case of migration to java platform, easy migration;
  • 2 Java Runtimes
  • ...


We are happy with what we have so far. We still have problems in terms of how to setup our development process. We will continue to look for perfect solution for our problems.

Other articles in this series

  1. How we build our web applications based on Domino
  2. Split back-end and front-end areas, they should not block each other and be independent as much as it is possible.
  3. Front-end guys should not have any knowledge about Domino, they don't need IBM Designer installed at all.
  4. Back-end guys must have knowledge about Domino, however they don't need to use IBM Designer, only in very rare cases. Backend should be done using only Java (no LS/SSJS/@Formula etc)
  5. Using Git+Jira is must and Jenkins server as builder server
  6. Auto-tests.

Monday, August 05, 2013

How we build our web applications based on Domino


I've been working with Domino for many years (however very possible less than many of you :-), I started to work with version 5 at the beginning and in few months we migrated to 6.X). I worked in few companies with absolutely different projects and processes of development. There were lot of 'hell projects' (without any structure inside, just mess) and few really 'cool projects' where I could learn something. I always tried to bring the best of the old projects into new. Now I'd like to describe how we develop applications in Domino today. No revolution in our approach, however I believe that is quite good one. The only required thing in that process - you must have time and desire to change process.
Time to improve

Team and projects

We are small and quite typical team: few back-end and front-end developers, manager and no QA as we do not do mistakes :). Roll out each 2 weeks with new features. We are developing CMS that manage external websites of our company.

Few very important points about websites we are doing here:
  • website's pages have to load extremely fast (means 200-400 ms to load page);
  • clean HTML, all (!) tags, attributes, javascripts should be controlled;
  • easy roll out from development environment to production environment without any interrupt for users.

Process of development

Now let's look on most important points of development process. I'll describe each point more deeply in upcoming posts this week. Possibly I will add more points during that time, lets see.
  1. Split back-end and front-end areas, they should not block each other and be independent as much as it is possible.
  2. Front-end guys should not have any knowledge about Domino, they don't need IBM Designer installed at all.
  3. Back-end guys must have knowledge about Domino, however they don't need to use IBM Designer, only in very rare cases. Backend should be done using only Java (no LS/SSJS/@Formula etc)
  4. Using Git+Jira is must and Jenkins server as builder server
  5. Auto-tests.
We've done almost all the list, some areas require some improvements however concept works and now it's only question of time. All front-end developers do not use IBM Designer in their daily job, back-end developers still use it (rarely), everything goes to GitHub, and then Jenkins take care about rest. That image illustrate what we have.
Domino development process overview
You are welcome to give your comments, idea, suggestions or something negative about that, everything can help and improve or process and wait for new posts soon :)

Other articles in this series

  1. How we build our web applications based on Domino
  2. Split back-end and front-end areas, they should not block each other and be independent as much as it is possible.
  3. Front-end guys should not have any knowledge about Domino, they don't need IBM Designer installed at all.
  4. Back-end guys must have knowledge about Domino, however they don't need to use IBM Designer, only in very rare cases. Backend should be done using only Java (no LS/SSJS/@Formula etc)
  5. Using Git+Jira is must and Jenkins server as builder server
  6. Auto-tests.

Friday, July 12, 2013

Replacement for DSAPI in Java/XPages

I've written few articles about how DSAPI could help you to control classic web application built on Domino. That solution worked perfect for us and difficulties I encountered were:
  • slower development process due to my skill in C;
  • poor documentations about how things work in DSAPI (probably most weak side for me);
  • deployment process (you need to create new DLL each time and upload it to Domno Server, then restart HTTP);
  • you have to be 'very-very' careful with everything, one mistake (i.e. memory leak somewhere) can crash the server at some point;

Last months we worked on new Web CMS based on Java/Velocity in Domino and result I must say was really great. I will make post about most interesting things later: the topic will be about java, html/templates, velocity, git, jenkins, jira and how it works together. I would call it pure Java approach to do development in Domino. The beauty using java as engine allow us to get rid of DSAPI. So everything what have been done with DSAPI (and in total I spend maybe 2-3 weeks) we replaced in 2-3 hours with Java.

case #1: Re-write URL from http://domain/page/subpage/ to http://domain/page/subpage with 301 status. We simply set new location in header and new status
  getResponse().setHeader(LOCATION_HEADER, uri);
case #2: 404/500 etc error pages we only set correct status for response + throw out required content

So my feeling about DSAPI is actually quite good, however be sure you know how to cook it, otherwise - don't go with that solution. Remember my example: I've spent weeks doing DSAPI via C and now we did exactly same in few hours. That feeling when I compared what I spent with DSAPI (via C) compare to new solution with Java. 100 hours agains 3.

Related topics
DSAPI for Domino
Rewriting URL in Domino using DSAPI
Solution for Lotus Domino to the trailing slash problem

Tuesday, October 09, 2012

What is comfort zone for Domino developers our days?

Lotus Script is no longer in my 'comfort zone' anymore but Java/JavaScript. That's actually it. We already moved all (well 90%) of backend to Java. Now Lotus Script serves only to provide validation/picklist/msgbox on forms/views for existing 'classic' applications. Now we are slowly moving everything to web and I like that.

We are aiming in few years to let our users to un-install LN and simply use browsers and that would be perfect. That time we should have no even 1 line LS and @Formula.

Monday, June 18, 2012

Content Is Not Allowed In Prolog

Got this issue in the morning. We have service that "aggregate" data from multiple RSS into 1 RSS. The issue appeared because at one of RSS we enabled encode option [encode UTF-8] but not [encode UTF-8 without BOM]:
encode in UTF-8
encode in UTF-8 without BOM.
our Java parse does not understand this BOM (byte order mark). So we just swtiched to one without BOM byte. I've made tests using this online tool, it worked just as I expected XMLValidator