Perform the procedures in this section to install and deploy the JasperReports Server WAR file in WebSphere.
Installing WebSphere and a Database
To install WebSphere and a database:
1. | Make sure you're using WebSphere 7.0.0.11. |
2. | Check that the WebSphere installation created a JAVA_HOME system environment variable. The variable needs to be set to the JAVA directory in the WebSphere installation. |
3. | Install the database (PostgreSQL, MySQL, Oracle, SQL Server, or DB2). |
The target database can be on a remote server. WebSphere should reside on the local machine. |
Preparing JasperReports Server Files
To prepare JasperReports Server files:
1. | Unpack jasperreports-server-6.1-bin.zip to a top-level directory. Unpacking the ZIP file creates the directory jasperreports-server-6.1-bin. |
2. | (Required) Manually create and load the JasperReports Server database. |
3. | (Optional) Manually create and load the sample databases. See Manually Creating the JasperReports Server Database for instructions. |
4. | (Required) Manually import the default users and organization. |
a. | Copy the <dbType>_master.properties file for your database from sample_conf and paste it to buildomatic: |
• | cd <js-install>/buildomatic |
• | Copy from — <js-install>/buildomatic/sample_conf |
• | Paste to — <js-install>/buildomatic |
For example, copy sample_conf/postgresql_master.properties to buildomatic.
b. | Rename the file you copied to default_master.properties. |
c. | Edit the default_master.properties file: |
• | Set appServerType to skipAppServerCheck. |
• | Change dbUsername, dbPassword, and dbHost to appropriate settings for your database. |
• | If you're using a port other than the default for your database, or if you've installed the database on a remote machine, change the dbPort field under Custom Properties to the appropriate settings. |
Each sample_conf/<dbType>_master.properties file contains appropriate sample values.
d. | Start your database server. |
e. | Open a Command Prompt as Administrator and run these commands: |
Buildomatic Targets to Execute
Commands
Description
cd <js-install>/buildomatic
Go to the buildomatic directory
js-ant create-js-db Create the jasperserver repository databasejs-ant init-js-db-pro
js-ant import-minimal-pro
Initializes database, loads core application data
js-ant create-sugarcrm-db
js-ant create-foodmart-db (Optional) Creates sample databasesjs-ant load-sugarcrm-db
js-ant load-foodmart-db (Optional) Loads sample data into the sample databasesjs-ant import-sample-data-pro
(Optional) Loads the demos that use the sample data
5. | Set up your license file. For information, refer to Setting Up the JasperReports Server License. |
Configuring CsrfGuard, Hibernate and Quartz Settings
Before deploying the JasperReports Server WAR file, update the CsrfGuard, Hibernate, Quartz, and settings as described here.
Configure CSrfGuard, Hibernate and Quartz settings in the WAR file:
1. | The WAR file is an archive format in a single file. Extract the Owasp.CsrfGuard.properties file using the command below: |
cd <js-install>"%JAVA_HOME%binjar" xf jasperserver-pro.war WEB-INF/esapi/Websphere.Owasp.CsrfGuard.properties[/code] |
The jar command creates the WEB-INF/esapi folder in the current location and places the extracted file there.
Open the WEB-INF/esapi/Owasp.CSrfGuard.properties file and delete the following line:
org.owasp.csrfguard.PRNG=SHA1PRNG
Then uncomment these two lines:
org.owasp.csrfguard.PRNG=IBMSecureRandom
org.owasp.csrfguard.PRNG.Provider=IBMJCE
Save the file.
2. | Copy the already configured files for hibernate.properties and js.quartz.properties to the WEB-INF folder. |
(Buildomatic configured these files for your database type in the steps above.)
From:
<js-install>/buildomatic/build_conf/default/webapp/WEB-INF/hibernate.properties
<js-install>/buildomatic/build_conf/default/webapp/WEB-INF/js.quartz.properties
To:
<js-install>/WEB-INF
3. | Edit the scheduler URI port value for WebSphere in the js.quartz.properties: |
Edit js.quartz.properties:
Set :
report.scheduler.web.deployment.uri=http://localhost:8080/jasperserver-pro
To:
report.scheduler.web.deployment.uri=http://localhost:9080/jasperserver-pro
4. | If you want to configure JasperReports Server to automatically schedule and email reports, enter your mail server information in the js.quartz.properties file. Modify all report.scheduler.mail.sender.* properties for your mail server. |
5. | Now that you have modified/updated the individual configuration files, you must replace them in the WAR file archive using the following commands. |
cd <js-install>"%JAVA_HOME%binjar" uf jasperserver-pro.war WEB-INF/hibernate.properties"%JAVA_HOME%binjar" uf jasperserver-pro.war WEB-INF/js.quartz.properties[/code] "%JAVA_HOME%binjar" uf jasperserver-pro.war WEB-INF/esapi/Owasp.CsrfGuard.properties[/code] |
6. | (WebSphere 8 only) If you're using WebSphere 8, enter the following additional commands: |
cd <js-install>zip -d jasperserver-pro.war WEB-INF/lib/stax-api-1.0.1.jarzip -d jasperserver-pro.war WEB-INF/lib/jta-1.1.jar[/code] |
7. | Delete the WEB-INF directory you created, along with the edited files it contains. |
Configuring a JDBC Provider in WebSphere
To configure a JDBC Provider in WebSphere:
1. | Launch the WebSphere Administrative Console and navigate to Resources > JDBC > JDBC Providers. |
2. | On the JDBC providers page, click the Guided Activity link at the top of the JDBC Providers page and follow Integrated Solutions Console instructions: |
a. | Configure credentials for a secure database. |
Use the J2C authentication aliases panel to create a new authenticated user.
In Global Security, click New and enter the user alias, user ID, and password. These are the credentials that WebSphere uses to access the database:
J2C Authentication Alias Settings
AliasExample User ID
Example Password
PostgreSQL
postgresql_jasperdb
postgres postgresMySQL
mysql_jasperdb
root passwordOracle
jasperserver_user
jasperserverpassword
DB2
db2admin_user
db2adminpassword
SQL Server
jasperserver_user
sa saa. | Connect to a database panel. From the Scope drop-down, choose Node:<node_name>,Server=<server_name> |
b. | Click the New button to create a new JDBC Provider. |
c. | Select your database type: |
• | If you're using PostgreSQL, MySQL, or a TIBCO JDBC driver — select User-defined. |
• | If you want to use the JDBC driver built and distributed by the MySQL project, see MySQL Example |
• | If you're using a vendor-supplied driver for DB2, Oracle, or SQL Server — select your database. |
d. | Select or enter these options. Your options depend on your database type. |
Database type | Implementation class name or type | Name |
---|---|---|
User-defined (PostgreSQL) | org.postgresql.jdbc2.optional.ConnectionPool | PostgreSQL JDBC Provider |
User-defined | com.mysql.jdbc.jdbc2.optional. | MySQL JDBC Provider |
User-defined (TIBCO JDBC Oracle) | tibcosoftware.jdbc.oracle.OracleDataSource | TIBCO JDBC Provider - Oracle |
User-defined (TIBCO JDBC SQL Server) | tibcosoftware.jdbc.sqlserver.SQLServerDataSource | TIBCO JDBC Provider - SQL Server |
User-defined (TIBCO JDBC DB2) | tibcosoftware.jdbc.db2.DB2DataSource | TIBCO JDBC Provider - DB2 |
DB2 Universal JDBC Driver Provider | Connection pool data source | DB2 Universal JDBC Driver Provider |
Oracle | Connection pool data source | Oracle JDBC Driver |
SQL Server | Connection pool data source | Microsoft SQL Server JDBC Driver |
3. | Click Next and enter the database classpath information for the JDBC provider. |
a. | For TIBCO JDBC drivers for Oracle, SQL Server, or DB2, locate the correct JAR in <js-install>buildomaticconf_sourcedb<your_database>jdbc: |
• | Oracle — <js-install>buildomaticconf_sourcedboraclejdbcji-oracle-driver-1.0.2.jar |
• | SQL Server — <js-install>buildomaticconf_sourcedbsqlserverjdbcji-sqlserver-driver-1.0.2.jar |
Note: For SQL Server 2008, use the vendor driver.
• | DB2 — <js-install>buildomaticconf_sourcedbdb2jdbcji-db2-driver-1.0.2.jar |
Copy the JAR file to a location in your WebSphere deployment and specify that location for the JDBC driver path.
If JasperReports Server is deployed on the same host as DB2, delete the following file to avoid conflicts: <db2>/SQLLIB/java/db2jcc.jar |
b. | For PostgreSQL, MySQL, and vendor drivers for Oracle, SQL Server, and DB2, enter the following: |
<js-install>buildomaticconf_sourcedb<your_database>jdbc
For example, enter:
C:jasperreports-server-6.1-binbuildomaticconf_sourcedbpostgresqljdbcpostgresql-9.2-1002.jdbc4.jar
Alternatively, you can copy the jar to a location in your WebSphere deployment and specify that location for the JDBC driver path.
If JasperReports Server is deployed on the same host as DB2, delete the following file to avoid conflicts: <db2>/SQLLIB/java/db2jcc.jar |
4. | Click Next to proceed to the next step. |
5. | Review the JDBC provider information you entered and click Finish. |
6. | Configure data sources and custom properties using one of these procedures: |
• | Defining a JNDI Name and Sample Data Sources for PostgreSQL and MySQL |
• | Defining a JNDI Name and Sample Data Sources for DB2 |
• | Defining a JNDI Name and Sample Data Sources for Oracle |
• | Defining a JNDI Name and Sample Data Sources for SQL Server |
Defining a JNDI Name and Sample Data Sources for PostgreSQL and MySQL
To define the JDBC data source and expose it through JNDI:
1. | Click the name of the JDBC provider that you just created. For example, PostgreSQL JDBC Provider. |
2. | Click Data sources in the Additional Properties of the JDBC provider details panel. |
3. | To create a new data source, click New. The new data source wizard appears. |
4. | Enter the data source name: jasperserver |
5. | Enter the JNDI name: jdbc/jasperserver |
6. | Click Next, choose Select an existing JDBC provider, then select PostgreSQL JDBC Provider or MySQL JDBC Provider from the drop-down list. |
7. | Click Next and accept the default helper class (com.ibm.websphere.rsadapter.GenericDataStoreHelper). Select the check box to use this data source in container managed persistence (CMP). |
8. | Click Next and select the Setup security aliases: |
Field Name | PostgreSQL Value | MySQL Value |
Component-managed authentication alias | <node>/postgresql_jasperdb | <node>/mysql_jasperdb |
Mapping configuration alias | DefaultPrincipalMapping | DefaultPrincipalMapping |
Container-managed authentication alias | <node>/postgresql_jasperdb | <node>/mysql_jasperdb |
9. | Click Next, review the summary information, and click Finish. |
To set the connection pool size:
1. | In the list of JDBC data sources, click the newly created jasperserver data source to edit it. |
2. | Click Additional Properties > Connection Pool Properties. |
You'll see that Maximum Connections is set to 10 by default.
3. | Set Maximum Connections to 50. You may want to set it to a higher value if necessary. |
4. | Click Save. |
To define custom properties:
1. | In the list of JDBC data sources, select the check box for the newly created jasperserver data source and click Test Connection. |
In the Messages area a success or failure message appears. The failure message gives you information about which custom properties you need to define. For example, in the case of PostgreSQL 9.0 and MySQL, a message indicates that the error is related to a null database name.
2. | Navigate to the jasperserver data sources General Properties page. |
3. | In Additional Properties on the right side of the General Properties page, click Custom properties. |
4. | Scroll down the list of properties and select databaseName. Set the value to jasperserver. |
5. | If you’re using MySQL, create a new property called url. Enter the following value and save the change: |
jdbc:mysql://localhost/jasperserver?useUnicode=true&characterEncoding=UTF-8
6. | Click Save directly to the master configuration. |
To create optional sugarcrm and foodmart data sources:
1. | If you plan to run the sample reports, use the following values to create the foodmart and sugarcrm JNDI data sources: |
Field Name | Value | |
---|---|---|
Data source name | foodmart | sugarcrm |
JNDI name | jdbc/foodmart | jdbc/sugarcrm |
2. | Click Save directly to the master configuration. |
3. | Set the connection pool size as described in To set the connection pool size. |
Next, deploy the WAR file in WebSphere as described in Deploying the JasperReports Server WAR File in WebSphere.
Defining a JNDI Name and Sample Data Sources for DB2
To define the JDBC data source and expose it through JNDI:
1. | Click the name of the JDBC provider you just created. For example, TIBCO JDBC Provider - DB2 or DB2 Universal JDBC Provider. |
2. | Click Data sources under the Additional Properties of the JDBC provider details panel. |
3. | To create a new data source, click New. The new data source wizard appears. |
4. | Enter the data source name: jasperserver |
5. | Enter the JNDI name: jdbc/jasperserver |
6. | Click Next. |
7. | (If you're using the TIBCO JDBC Provider, skip to step 9.) If you're using the vendor's DB2 driver, choose Select an existing JDBC provider, then select DB2 Universal JDBC Provider from the drop-down list. |
8. | Click Next and enter these values: |
Field Name | Value |
---|---|
Driver type | 4 |
Database name | jsprsrvr |
Server name | localhost |
Port number | 50000 |
9. | Select Use this data source in CMP and click Next. |
10. | On the Setup security aliases page, enter the following value for Component-managed authentication alias: |
<node>/db2admin_user
11. | Click Next, review the summary information, and click Finish. |
To set the connection pool size:
1. | In the list of JDBC data sources, click the newly created jasperserver data source to edit it. |
2. | Click Additional Properties > Connection Pool Properties. |
You'll see that Maximum Connections is set to 10 by default.
3. | Set Maximum Connections to 50. You may want to set it to a higher value if necessary. |
4. | Click Save. |
To define custom properties:
1. | In the list of JDBC data sources, select the check box for the newly created jasperserver data source, and click Test Connection. |
2. | In the Messages area a success or failure message appears. The failure message gives you information about which custom properties you need to define. |
3. | Edit the following properties, adding any that are missing, then save the changes: |
Properties for TIBCO JDBC Driver for DB2
Property Name Value alternateID JSPRSRVRbatchPerformanceWorkaround
truecurrentSchema
JSPRSRVR
databaseName
JSPRSRVRserverName
localhost portNumber 50000 To see a list of all properties available for the TIBCO JDBC driver for DB2, see the Progress DataDirect documentation at http://media.datadirect.com/download/docs/jdbc/alljdbc/help.html and navigate to User's Guide > DataDirect Connect Drivers > DB2 Driver > Connection Properties. |
Properties for Vendor JDBC Driver for DB2
Property Name ValuecurrentSchema
JSPRSRVR
fullyMaterializeLobData
true
fullyMaterializeInputStreams
true
progressiveStreaming
2
progressiveLocators
2
4. | Go back to the list of JDBC data sources, select the check box for the jasperserver data source, and click Test Connection. |
To create optional sugarcrm and foodmart data sources:
1. | If you plan to run the sample reports, use the following values to create the foodmart and sugarcrm JNDI data sources: |
Field Values for Optional Data Sources for All DB2 Drivers with WebSphere
Field NameValue
Data source name
foodmart
sugarcrm
JNDI name
jdbc/foodmart
jdbc/sugarcrm
Component-managed authentication alias
<node>/db2admin_user
Database name
foodmart
sugarcrm
Driver type
4
Server name
localhost
Port number
50000
Use this data source in CMP
selected
Custom Properties for TIBCO JDBC Driver for DB2 with WebSphere
Property NameValue
alternateID FOODMART SUGARCRM batchPerformanceWorkaroundtrue
currentSchema
FOODMART
SUGARCRM
databaseName FOODMART SUGARCRM serverNamelocalhost
Custom Properties for Vendor's Driver for DB2 with WebSphere
Property NameValue
currentSchema
FOODMART
SUGARCRM
resultSetHoldability
1
2. | Click Save directly to the master configuration. |
3. | Set the connection pool size as described in To set the connection pool size. |
Next, deploy the WAR file in WebSphere as described in Deploying the JasperReports Server WAR File in WebSphere.
Defining a JNDI Name and Sample Data Sources for Oracle
To define the JDBC data source and expose it through JNDI:
1. | Click the name of the JDBC provider you just created. For example, TIBCO JDBC Provider - Oracle or Oracle JDBC Driver. |
2. | Click Data sources in the Additional Properties of the JDBC provider details panel. |
3. | To create a new data source, click New. The new data source wizard appears. |
4. | Enter the data source name: jasperserver |
5. | Enter the JNDI name: jdbc/jasperserver |
6. | Click Next. |
7. | (If you're using the TIBCO JDBC Provider, skip to step 9.) If you are using the vendor's Oracle driver,choose Select an existing JDBC provider, then select Oracle JDBC Driver from the drop-down list. |
8. | Click Next and enter the following values: |
Field Name | Value |
---|---|
URL | jdbc:oracle:thin:@localhost:1521:orcl |
Data store helper class name | Oracle11g data store helper |
Use this data source in CMP | selected |
9. | Click Next and in Setup security alias, set Component-managed authentication alias to the following value: |
<node>/jasperserver_user
10. | Click Next, review the summary information and click Finish. |
To set the connection pool size:
1. | In the list of JDBC data sources, click the newly created jasperserver data source to edit it. |
2. | Click Additional Properties > Connection Pool Properties. |
You'll see that Maximum Connections is set to 10 by default.
3. | Set Maximum Connections to 50. You may want to set it to a higher value if necessary. |
4. | Click Save. |
To define custom properties:
1. | In the list of JDBC data sources, select the check box for the newly created jasperserver data source and click Test Connection. |
In the Messages area a success or failure message appears. The failure message gives you information about which custom properties you need to define.
2. | Navigate to the jasperserver data sources General Properties page. |
3. | In Additional Properties on the right side, click Custom properties. |
4. | Edit the following properties, adding any that are missing, then save the changes. The following table shows how to set the custom properties if you're using the TIBCO JDBC driver for Oracle: |
Custom Properties for TIBCO JDBC Driver for Oracle
Property Name Value serverName localhost SID ORCLportNumber
1521
batchPerformanceWorkaround true To see a list of all properties available for the TIBCO JDBC driver for Oracle, see the Progress DataDirect documentation at http://media.datadirect.com/download/docs/jdbc/alljdbc/help.html and navigate to User's Guide > DataDirect Connect Drivers >Oracle Driver > Connection Properties. |
5. | Go back to the list of JDBC data sources, select the check box for the jasperserver data source, and click Test Connection. |
To create optional sugarcrm and foodmart data sources:
1. | If you plan to run the sample reports, use the following values to create the foodmart and sugarcrm JNDI data sources: |
Field Name | Value | |
---|---|---|
Data source name | foodmart | sugarcrm |
JNDI name | jdbc/foodmart | jdbc/sugarcrm |
Component-managed authentication alias | <node>/foodmart_user | <node>/sugarcrm_user |
Property Name | Value | |
---|---|---|
portNumber | 1521 | |
serverName | localhost |
2. | Click Save directly to the master configuration. |
3. | Set the connection pool size as described in To set the connection pool size. |
Next, deploy the WAR file in WebSphere as described in Deploying the JasperReports Server WAR File in WebSphere.
Defining a JNDI Name and Sample Data Sources for SQL Server
To define a JDBC provider:
1. | Click the name of the JDBC provider you just created. For example, Microsoft SQL Server JDBC Driver. |
2. | Click Data sources under the Additional Properties of the JDBC provider details panel. |
3. | To create a new data source, click New. The new data source wizard appears. |
4. | Enter the data source name: jasperserver |
5. | Enter the JNDI name: jdbc/jasperserver |
6. | Click Next. |
7. | (If you're using the TIBCO JDBC Provider, skip this step.) If you're using the vendor's SQL Server driver, choose Select an existing JDBC provider, then select Microsoft SQL Server JDBC Driver from the drop-down list. |
8. | Click Next and in Setup security alias, set Component-managed authentication alias to the following value: |
jasperserver_user
9. | Click Next, review the summary information and click Finish. |
To set the connection pool size:
1. | In the list of JDBC data sources, click the newly created jasperserver data source to edit it. |
2. | Click Additional Properties > Connection Pool Properties. |
You'll see that Maximum Connections is set to 10 by default.
3. | Set Maximum Connections to 50. You may want to set it to a higher value if necessary. |
4. | Click Save. |
To define custom properties:
1. | In the list of JDBC data sources, select the check box for the newly created jasperserver data source, and click Test Connection. |
In the Messages area a success or failure message appears. The failure message gives you information about which custom properties you need to define.
2. | Navigate to the jasperserver data sources General Properties page. |
3. | In Additional Properties on the right side of the page, click Custom properties and define properties. The following table shows how to set properties if you are using the TIBCO JDBC driver for SQL Server |
Custom Properties for TIBCO JDBC Driver for SQL Server
Property Name Value batchPerformanceWorkaround true databaseName jasperserver serverName localhostportNumber
1433
To see a list of all properties available for the TIBCO JDBC driver for SQL Server, see the Progress DataDirect documentation at http://media.datadirect.com/download/docs/jdbc/alljdbc/help.html and navigate to User's Guide > DataDirect Connect Drivers >Microsoft SQL Server Driver > Connection Properties. |
To create optional sugarcrm and foodmart data sources:
If you plan to run the sample reports, use the following values to create the foodmart and sugarcrm JNDI data sources:
1. | In the list of JDBC data sources, click the link for the newly created jasperserver data source. |
2. | Click Save directly to the master configuration. |
3. | Set the connection pool size as described in To set the connection pool size. |
Deploying the JasperReports Server WAR File in WebSphere
To deploy the JasperReports Server WAR file in WebSphere:
1. | In the Administrative Console, navigate to Applications > New Application and select New Enterprise Application. |
JasperReports Server is a modern application, based on Java Servlet version 2.4, so you do not select the older, WebSphere V4‑compliant application type.
2. | Browse to <js-install>/jasperserver-pro.war on the local file system. Keep the default setting (Fast path) selected and click Next. |
3. | On the Select installation options page, accept all the default settings and click Next. |
4. | On the Map modules to servers page, make sure the JasperReports Server module is mapped to the cell, node, and server that you want. Click Next. |
5. | On the Map modules to servers page, select jasperserver. Click Next. |
6. | On the Map resource references to resources page, map the resources you want: |
a. | First, select the Browse button under the jdbc/jasperserver resource. In the page that opens, select the jdbc/jasperserver radio button, and click Apply. Then select the check box next to the jdbc/jasperserver resource. |
b. | If you plan to run the sample reports, follow the same steps for jdbc/surgarcrm and jdbc/foodmart, making sure to select the correct radio button for each one. |
c. | When you have mapped all resources, select the check boxes next to every resource have mapped. |
d. | Click Next. |
7. | On the Map virtual hosts page, choose the JasperServer UI application module. Click Next. |
8. | In the Map context roots for Web modules, enter jasperserver-pro. |
9. | Click Next, review the summary information and start the installation process. (The installation process may take a while.) |
10. | Click Save directly to the master configuration. |
Setting JVM Options
To set the Java JVM Options:
For the JasperReports Server XML/A functionality to work, special Java JVM options need to be set to resolve class conflicts between the WebSphere and JasperReports Server web services implementation. JVM options also provide the optimal resources for running JasperReports Server.
To configure your Java JVM options:
1. | Select Enterprise Applications > jasperserver-pro_war > Target specific application status > (server name). |
2. | Expand Java and Process Management > Process Definition > Java Virtual Machine > Generic JVM arguments. |
3. | In the Generic JVM Options text box, paste in the following JVM options that explicitly specify JasperReports Server classes for AXIS and Xalan, as well as optimize JVM resources: |
Generic JVM Options on Windows | |
Options for all databases | |
For Oracle | set JAVA_OPTS=%JAVA_OPTS% -Doracle.jdbc.defaultNChar=true[/code] |
Generic JVM Options on Linux | |
Options for all databases | |
For Oracle | export JAVA_OPTS="$JAVA_OPTS -Doracle.jdbc.defaultNChar=true"[/code] |
Setting the Oracle localization option, defaultNChar, can substantially impact the performance of JDBC queries. If you don't need to support UTF-8 for your Oracle database, you can omit this setting. |
4. | Click Save on the console task bar. |
To configure class loading:
1. | Select Enterprise Applications > jasperserver-pro_war > Class loading and update detection. |
2. | In the section Class loader order, select Classes loaded with local class loader first (parent last). |
3. | (WebSphere 8.x only) In the WAR class loader policy section select Single class loader for application. |
4. | Save directly to your master configuration. |
5. | Restart WebSphere. |
Starting and Restarting JasperReports Server
To start the jasperserver-pro application:
1. | Restart WebSphere. |
2. | In the Administrative Console, navigate to: Applications > Application Types > WebSphere Enterprise Application. |
3. | Select the check box next to the jasperserver-pro application and click Start. If you make configuration changes to your JasperReports Server instance, restart JasperReports Server. |
4. | Log into JasperReports Server. |
Recommended Comments
There are no comments to display.