Troubleshootings

Installation path problems

Be careful to avoid the installation of Tomcat in paths having a space ‘‘ in folders: Windows operating system could have problems in recognizing the correct path.

Installation listening port problems

Moreover, pay attention to the port configured in Tomcat: in Linux/Unix O.S. you could have to change OS settings in order to allow the use of that port by Tomcat.

In order to run Tomcat, you can execute the command tomcat/bin/catalina.sh run or catalina.bat run, according to the o.s. in use; pay attention to the fact that in Linux/Unix/MacOS o.s. you have to change the permissions for those files, in order to execute them, use the command: “chmod u=rwx *.sh” to make these files executable.

If you have changed the HTTP port in tomcat/conf/server.xml file, the URL to use in the browser to connect to 4WS.Platform changes as well. Be careful not to use a port already used by other services. In order to check it out, open a shell and execute the command “netstat”: if a service is already using the same port, you will be see it through that command.

Database connection problems

Another common problem is due to a wrong database connection configuration or because of the lack of the JDBC driver; any java program needs a JDBC driver to connect to a database. Remember to include it (one or more .jar files) into tomcat/lib folder. According to the database type you have chosen, you can download such a driver from the database vendor offical web site: search for JDBC driver in its web site.

In all these cases, check out the log generated by Tomcat when starting it: tomcat/logs/catalina.out or tomcat/logs/localhost.0.log

It will report any configuration error or problems like the ones described above.

Execution problems

There could be problems when executing the product, due to several reasons:

network connection problems between the web browser and the tomcat

suggestions:

check the quality of the network between the two layers

check out the amount of data you send between the server and the client side (e.g. the data provided to grids, lookups, remote combo boxes); the way you configured an applicatio can have detrimental effects on the performance of the application itself

network connection problems between Tomcat and a database server

suggestions:

check the quality of the network between the two layers

check out if there is a firewall which could close database connections still opened after a while; Platform, as the majority of the web applications, uses a database connection pooler inside, in order to speed up the execution of the business logic; that means that these connections cannot be closed externally

check out if there is an automatism on the database server which closes connections on its side after a while

memory consumption on Tomcat; there are two kinds of memories used by Tomcat: PermGen and Heap Memory. Each can be configured when defining the service which starts Tomcat or on the catalina.sh/bat o service.sh/bat files

Typical settings for these memory are 256Mb for PermGen e 768Mb for the Heap Memory, but these should be changed according to the specific configured application.

In order to retrieve information about the current status of the web application, there is a public web service that can be invoked. This web service checks the availability of database connections to the main repository (database) and returns a HTTP 200 code in case fo successful test, otherwise, it returns a 500 error code + an error message reporting the cause of the problem.

Apart from the HTTP code, an HTML message is also provided, reporting times related to getting a connection and the execution time for a query: these times could be helpful to figure out if there is an overload on the database server.

The web service can be invoked through this URL:

http://host:port/platform/healthCheck

and it could be scheduled to be executed automatically through the Platform Scheduler: a notification email could be sent in case of 500 error code, to inform a system administrator abour a problem with the application.

The web service accepts two additional parameters, in order to fetch additional information:

checkAdditionalDatasources=Y

when adding this parameter to the URL, every configured additional data source will be checked out too. Time required to get the connection is also reported.

getAdditionalInfo=Y

when adding this parameter to the URL, every System property is also reported, as well as the memory usage (total memory, used memory, free memory).

Example of an URL which returns a detail info about the web application status:

http://host:port/platform/healthCheck?getAdditionalInfo=Y&checkAdditionalDatasourcesToo=Y

network connection problems between a remote client and a Platform installation

In case the end users report a slow performance when retrieving or sending data to a Platform server (e.g. using a web application based on Platform or invoking web services), the bad performance can be due to a variety of different causes, which can be sum up in:

  • a slow internet connection, used by the end user

  • an application functionality not optimized, in terms of memory consumption or managed data

  • too many requests to the server at the same time

  • a slow performance due to the server (hardware)

  • a slow performance due to the database server used by the Platform server

Each of these potential issues must be carefully evaluated and they are discusses in detail in the next few sections.

a slow internet connection, used by the end user

It is not easy to prove that a problem resides on the poor internet connection used by the end user to communicate with the Platform server, since often this issues is temporary and it could not be identified later, when someone else is dealing with that problem and wanting to figure it out.

In order to promptly and easily facilitate the evaluation of this problem, there is a functionality available at AppDesigner level, which can be used to evaluate the client internet connection: simply go to Help -> Network Test and a test will be automatically carried out by Platform, related to: latency, download/upload transfer rate. The outcome of this test is reported to the user a few seconds afterwards. The same results are also automatically saved by Platform in CON60_LOGS, as an application event, which can be shown at any time using the functionality Monitoring -> Log Server -> Table Logs and choosing Net Test events.

It is possible to include the same network test functionality within the web application, by following these steps:

  • create a client-side javascript action and include in it the instruction:

netTest();
  • create a new menu item, using the App Designer Menu item, choosing the option "Execute action" and link to it the just created action

In this way, the Network Test functionality can be accessed by the end users, without using the AppDesigner.

There is also a third option: programmatically execute it, without a visual prompt to the user. In order to do it, just invoke the global client-side method netTest from any client-side javascript action, using the following code:

var myCallbackFunction = function(latency,downloadRate,uploadRate) { 
  // latency: expressed in ms, download/uploadRate: expressed in Kb/sec
  // do something with the arguments...
}
netTest(myCallbackFunction);

an application functionality not optimized, in terms of memory consumption or managed data

This is probably the most difficult issue to recognize, since it is often due to a poor design activity.

A good way to identify these kind of issues is using the AppDesigner functionality named App Diagnosis, available in

Monitoring -> Application Log -> App Analysis

Thanks to this feature, it is possible to identify a wide range of issues, due to slow queries, too many records fetched, database connection errors, memory consumption and much more.

too many requests to the server at the same time

It is important to pay attention to the number of HTTP requests coming to the server, especially in case of many web service calls. A large number of requests could:

  • saturate the network bandwidth available at server layer

  • reach the maximum amount of sockets (ports) available at operating system level and create HTTP network errors

  • reach the maximum amount of database connection and create database connection errors

  • consume too much CPU on the server and consequently slow down the perfomance of the whole system

When creating web services and by and large creating a web application, it is important to pay attention to a few key elements, including: average number of end users connecting to the web app, average number of web service calls per second, how complex the web service logic is.

If the number of end users is higher than a hundred or the number of web service calls per second is more than a unit, it is strongly recommended to carry out a stress test, before going to production, for example by using a free tool like Apache JMeter.

Another option is to set up a cluster of servers in order to manage a wide number of connections, with auto-scale option if available, in order to manage peaks of connections.

It is important to execute a fine tuning of the database as well, in terms of max number of concurrent connections it can manage and optionally increase the default number, according to the number of users/web service calls. The max nr of database connections at pooler level can be changed as well, if needed, by editing the c3p0.properties file available within WEB-INF/classes folder of the Platform server installation (the property named c3p0.maxPoolSize) and the max time to wait for a connection (property named c3p0.checkoutTimeout, expressed in ms).

A good tool embedded in the App Designer to use to figure out the amount of HTTP requests coming to the server is available through Monitoring -> Application Log -> Log Statistics

where all incoming requests are reported and grouped by type and day.

Moreover, a more detail report reports the figure along the day, grouping the requests per hour of day. The same chart reports also the consumption of CPU, so it is possible to figure out how requests are affecting the CPU usage.

a slow performance due to the server (hardware)

A heavy load due to the application logic on the server obviously affects the server (hardware) performance. The server can be sized accordingly to the nature of the app and its complexity. If needed, a cluster of servers should be introduced.

A good approach is also to limit the execution of enqueued elements and scheduled processed in a dedicated server of the cluster: in this way, the performance of the on-line part of the application, accessed by the end users, would not be affected by the batch part.

a slow performance due to the database server used by the Platform server

Another typical bottleneck in a system is represented by the database: this must be carefully tuned and monitored over time.

The diagnosis tool provided by Platform (Monitoring -> Application Log -> App Analysis) is an helpful resource to use in order to recognize problems due to the database, such as:

  • timeout when retrieving a database connection, often due to a pool size not correctly set and to increase, as well as the max number of connections at database level to set

  • slow queries

  • database locks, often due to design errors when creating the application

out of memory errors when exporting a large amount of rows from a grid

It is a very bad idea to show on grid a large amount of columns, which should never be larger than a hundred columns. Even worse, it is trying to export a large amount of rows: this would lead to a long waiting time to export the whole content and a very high memory consumption.

In such a scenario, it is strongly recommended to:

  • limit the number of columns to export

  • apply as many filtering conditions as possible, in order to limit the total amount of rows to export

  • export always in CSV format: xls/xlsx formats consume a very large amount of memory and consequently they should be avoided

  • export data in "stream mode", i.e. the server will generate the CSV content step by step and return the CSV as a stream of data, so that the server memory consumption is limited and the export time is reduced; in order to do it, add a "before load data" event to the grid and include in the client-side javascript action the following scriptlet:

gridXXX.store.baseParams.streamExport = "Y"; 
// use this scriptlet to force the grid data export in stream mode, 
// i.e. to generate the CSV content step by step, when exporting the grid content
// in this way, the memory consumption is limited and the export if faster
// IMPORTANT NOTE: do not use this hint if your grid is filled by a 
// javascript based business component where the grid content is generated 
// (i) starting from multiple seocndary queries 
// or 
// (ii) the whole result set is fetched

Moreover, it is also suggested to enqueue the export task, in order to take control of the memory consumption, since there can be many concurrent uses who try to export data at the same time.

Consequently, see also the next section.

very slow export from grid, due to many concurrent exports

In case there are many concurrent uses who try to export data at the same time, the CPU usage and the memory consumption can reach critical levels. In order to limit the resource consumption, it is a god practice to enqueue the export tasks, at least for the most critical ones (i.e. the ones who involves a large amount of cells to export).

It is possible to activate the export enqueuing at grid level, through the "before export" event, where linking a client-side javascript action containing the following scriptlet:

return {
  enqueue: true
};

error while generating a report using Jasper Report

If you are executing for the first time a report in a new environment using Jasper Report, you could bump into this error:

// Some codeCould not initialize class net.sf.jasperreports.engine.util.JRStyledTextParser
java.lang.NoClassDefFoundError: Could not initialize class net.sf.jasperreports.engine.util.JRStyledTextParser

If it is so, you have to include a Java directive in the Tomcat service configuration:

-Djava.awt.headless=true

Finally, restart the Tomcat service.

Error while reading email messages

Platform distribution can work within a Tomcat web container or inside Google App Engine container.

According to the execution environment, a library is needed to work correctly.

If you get the following error

java.lang.NoSuchMethodError: javax.mail.internet.ParameterList.combineSegments()V at com.sun.mail.imap.protocol.BODYSTRUCTURE.parseParameters(BODYSTRUCTURE.java:424) at com.sun.mail.imap.protocol.BODYSTRUCTURE.(BODYSTRUCTURE.java:244) at com.sun.mail.imap.protocol.BODYSTRUCTURE.(BODYSTRUCTURE.java:110) at com.sun.mail.imap.protocol.FetchResponse.parseItem(FetchResponse.java:244) at com.sun.mail.imap.protocol.FetchResponse.parse(FetchResponse.java:199)

when trying to read email messages from Platform standard edition (within Tomcat), it means there is a library to remove from WEB-INF/lib subfolder of Platform web application: you have to remove

appengine-api-1.0-sdk-1.9.64.jar

Error while executing a server-side javascript action

If you encounter the error "Encountered code generation error while compiling script: generated bytecode for method exceeds 64K limit", it means that the source code is too big and overpasses the 64k max compiled code.

This can be due to two alternative causes:

  • you are passing forward to this action as argument a "vo" too big as a source code; to check it out, look at the actions list and find the current action: if the check box named "pass input as source code" is selected, then uncheck it

  • you have created an action containing mainly commands and not declarations; it would be better to organize the source code with many more function declarations and minimize the amount of code related to commands, so that the real commands are focused only on function calls. This is also the best choice also from the point of view of the unit test, since this is based on the availability of code distributed within functions.

Last updated