Enable CGI support in Tomcat for your application:

2 configuration files in the application directory will need to be updated: web.xml and context.xml. The latter does not probably exist, so you will need to create it.

cd /home/dataexplorer1/projects/java/cbaadmin/src/main/webapp/WEB-INF

vi web.xml

<servlet>
<servlet-name>cgi</servlet-name>
<servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
<init-param>
<param-name>cgiPathPrefix</param-name>
<param-value>WEB-INF/cgi</param-value>
</init-param>
<init-param>
<param-name>executable</param-name>
<param-value></param-value>
</init-param>

<init-param>
<param-name>passShellEnvironment</param-name>
<param-value>"true"</param-value>
</init-param>

<init-param>
<param-name>environment-variable-LD_LIBRARY_PATH</param-name>
<param-value>/usr/local/lib64:/usr/lib64:/usr/lib64/graphviz:/app/hadoop/lib/native:/usr/pgsql-10/lib</param-value>
</init-param>

<load-on-startup>5</load-on-startup>
</servlet>


<servlet-mapping>
<servlet-name>cgi</servlet-name>
<url-pattern>/cgi-bin/*</url-pattern>
</servlet-mapping>

cd /home/dataexplorer1/projects/java/cbaadmin/src/main/webapp/

mkdir META-INF

cd META-INF

vi context.xml

<Context privileged="true">
</Context>

Create cgi directory

mkdir /home/dataexplorer1/projects/java/cbaadmin/src/main/webapp/WEB-INF/cgi



Create and compile an application

cd /home/dataexplorer1/projects/java/cbaadmin/src/main/webapp/WEB-INF/cgi

vi a.cpp

#include<iostream>
using namespace std;

int main(int argc,char** argv,char** pEnv)
{
cout<<"Content-type: text/html"<<endl;
cout<<endl;
cout<<endl;
cout<< "<HTML>"<<endl;
cout<< "<BODY>"<<endl;
cout<< "hello world of C++"<<endl;

cout<<"<OL>"<<endl;
while (*pEnv)
{
cout<<"<LI>"<<*pEnv++<<"</LI>"<<endl;

}
cout<<"</OL>"<<endl;


cout<< "</BODY>"<<endl;
cout<< "</HTML>"<<endl;
return 0;
}


c++ a.cpp

verify it runs :

a.out



Deploy the war

cd /home/dataexplorer1/projects/java/cbaadmin

mvn package

cp /home/dataexplorer1/projects/java/cbaadmin/target/cbaadmin-1.war /tmp/cbaadmin.war

Deploy into the Tomcat using manager app at http://r02edge.custom-built-apps.com:1962/manager/html


Update the permissions for the cgi apps in webapps as tomcat

su - tomcat

cd /app/apache-tomcat-9.0.34/webapps/cbaadmin/WEB-INF/cgi

chmod 755 a.cgi

Execute the application from browser

http://r02edge.custom-built-apps.com:1962/cbaadmin/cgi-bin/a.out

execute application dependent on shared libraries

Note that LD_LIBRARY_PATH is seen by the application environment in the above example.

This enables C/C++ applications that are dynamically linked to be able to resolve their dependencies, provided the shared libraries are in the LD_LIBRARY_PATH

To illustrate the example the cadence C++ application is put into the cgi-bin in /app/apache-tomcat-9.0.34/webapps/cbaadmin/WEB-INF/cgi

The application generates a graph from the list of nodes and their dependencies, renders the graph as png and places it in the webapplication images directory

it contains (amongst the other lines) the following:

CODE SNIPLET:

for (vector<pair<string,string> >::iterator iter=cadence.begin();iter != cadence.end();iter++)
{
myGraph.addEdge(iter->first,iter->second);
}

string filename="/app/apache-tomcat-9.0.34/webapps/cbaadmin/images/workflow.png";
myGraph.RenderPng(filename);

cout<<"Content-type: text/html"<<endl;
cout<<endl;
cout<<endl;
cout<< "<HTML>"<<endl;
cout<< "<BODY>"<<endl;
cout<<"<H1>Cadence</H1>"<<endl;

cout<<"The graph of nodes cadence are generated </BR>"<<endl;
cout<<"<IMG src=/cbaadmin/images/workflow.png height=180 widht=400></IMG>"<<endl;
cout<< "</BODY>"<<endl;
cout<< "</HTML>"<<endl;

END OF CODE SNIPPLET

the application depends on the library libcbaGraph.so and a set of specific libraries:

[tomcat@r02edge cgi]$ ldd cadence
linux-vdso.so.1 => (0x00007ffe0b1b2000)
librt.so.1 => /usr/lib64/librt.so.1 (0x00007f8e12b4a000)
libpthread.so.0 => /usr/lib64/libpthread.so.0 (0x00007f8e1292e000)
libcbaGraph.so => /usr/local/lib64/libcbaGraph.so (0x00007f8e1272b000)
libgvc.so.6 => /usr/lib64/libgvc.so.6 (0x00007f8e12491000)
libcgraph.so.6 => /usr/lib64/libcgraph.so.6 (0x00007f8e1227b000)
libstdc++.so.6 => /usr/local/lib64/libstdc++.so.6 (0x00007f8e11f00000)
libm.so.6 => /usr/lib64/libm.so.6 (0x00007f8e11bfe000)
libgcc_s.so.1 => /usr/local/lib64/libgcc_s.so.1 (0x00007f8e119e7000)
libc.so.6 => /usr/lib64/libc.so.6 (0x00007f8e11619000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8e12d52000)
libltdl.so.7 => /usr/lib64/libltdl.so.7 (0x00007f8e1140f000)
libxdot.so.4 => /usr/lib64/libxdot.so.4 (0x00007f8e1120a000)
libcdt.so.5 => /usr/lib64/libcdt.so.5 (0x00007f8e11003000)
libpathplan.so.4 => /usr/lib64/libpathplan.so.4 (0x00007f8e10dfa000)
libexpat.so.1 => /usr/lib64/libexpat.so.1 (0x00007f8e10bd0000)
libz.so.1 => /usr/lib64/libz.so.1 (0x00007f8e109ba000)
libdl.so.2 => /usr/lib64/libdl.so.2 (0x00007f8e107b6000)


libcbaGraph.so has been installed into /usr/local/lib64

the required version of libstdc++ can be found in /usr/local/lib64

this called for setting up LD_LIBRARY_PATH to have /usr/local/lib64 as the first path in search.

setting up LD_LIBRARY_PATH has been accomplished by setting CGI servlet parameter :

<init-param>
<param-name>environment-variable-LD_LIBRARY_PATH</param-name>
<param-value>/usr/local/lib64:/usr/lib64:/usr/lib64/graphviz:/app/hadoop/lib/native:/usr/pgsql-10/lib</param-value>
</init-param>

with the LD_LIBRARY_PATH in place the application can run and find the shared objects it is dependent on: