Skip to Content

Have you ever asked yourself or even been confronted with the task of deploying already compiled Java libraries with or in an MTA application? This would be a frequent requirement, if you are to port existing Java code in an MTA application you are to develop on XSA.

And this is something we encountered in a project we conducted several weeks ago. A solution provider had a solution implementing planning and predictive use cases in the data science area. The solution used a remote database holding the mining data. The business logic was implemented in Java and ran on a Tomcat utilizing licenced 3rd party libraries from a well-known product vendor. The idea was to port the existing code and the 3rd party libraries on XSA and thus use HANA as the underlaying database with its data mining capabilities. In addition to this, we were to extend the solution’s code leveraging HANA APIs and functionalities.

Now there is one issue with this scenario, which is common to all such porting tasks. One major part of the XSA toolbox is the Web IDE (for SAP HANA). The Java code in the Web IDE is handled by Maven in the background. This means that if your 3rd party libraries are not Maven compliant, you won’t be able to import them to your MTA. Technically you will be able to import the jar files into the MTA, but the build of the archive will fail. This is because such libraries don’t have a Maven specific pom.xml. Consequently their dependencies are unknown and Maven refuses to run the build.

In the following I will lay out the steps you need to perform, which will get you out of this maze. I will do it in a rather detailed fashion, but please bear with me, even though I know that many of you are already familiar with the concepts I will be introducing here.

Basically I did two things:

  • “mavenized” the 3rd party libraries, which were not maven compliant,
  • Imported them “correctly” into the MTA project of the Web IDE.

The rest is managed by the Web IDE and the deploy service of XSA.

Prerequisites and Preliminary Work

Everything I will be sharing here you will be able to do yourself on your cloud or on-premise HANA instance (HANA Express for example). I used an on-premise instance of HANA 2.0 SPS02.

I wrote a simple Java class com.helper.vehicles.Car in my Eclipse IDE, which at the end I have exported as a JAR file. I named it vehicles.jar. Please note that this archive is not Maven compliant. The class Car has two attributes: manufacturer and yearOfProduction and the corresponding setter and getter methods. By the end of this blog I will use this exemplary code in a servlet of the Java module calling one of these methods on the instance of a Car thus demonstrating the successful deployment of the MTA. Here is the class Car (just for the sake of completeness; nothing exciting happens here):

package com.helper.vehicles;

public class Car {
	
	public String manufacturer;
	public int yearOfProduction;
	
	public String getManufacturer() {
		return this.manufacturer; 
	}
	
	public int getYearOfProduction() {
		return this.yearOfProduction;
	}
	
	public void setManufacturer(String manufacturer) {
		this.manufacturer = manufacturer;
	}
	
	public void setYearOfProduction(int yearOfProduction) {
		this.yearOfProduction = yearOfProduction;
	}
}

I also had (and still have) a Maven installation on my local Windows machine – version 3.5.0 (not that the version really matters).

Setting up the Web IDE Project

I used the project wizard of the Web IDE and named the MTA project car_fleet.

I created a Java module under the MTA and named it vehicles_java. Please note that for simplicity reasons I didn’t enable the HANA database support (HDI container pre-configuration). I didn’t want to make any database calls, since the main purpose is to demonstrate the integration of the Java libraries.

While creating the Java module I again used the wizard and chose the option “Simple Web Application”. The wizard then also generates a servlet called HelloServlet (in the package you specify in the wizard). I had changed its name to VehiclesServlet – you don’t have to do this. It gives me (and you) a certain code skeleton I can use for my rapid deployment. This is what the result looked like:

The VehiclesServlet is under the src folder (it is not expanded in this screen shot, but believe me … it’s there). But what you can already see is the pom.xml of the Java module! As I stated before: the Web IDE always uses Maven in the background and this is the proof … for the sceptics among you.

“Mavenizing” the vehicles.jar

To make the vehicles.jar Maven compliant I needed at least three Maven properties: a groupId, an artifactId and a version. Then I issued the following command on my local machine:

mvn install:install-file -Dfile=<PATH_TO_THE_JAR>/vehicles.jar -DgroupId=company -DartifactId=vehicles -Dversion=1.0 -Dpackaging=jar

I suppose the options in the command are self-explanatory. Note the assignment of the properties and their values (groupId=company, artifactId=vehicles, version=1.0).The result is a folder/directory structure in the repository of my local Maven installation. Under the folder “version” resides the actual (renamed) jar alongside with its corresponding pom.xml.

Note that the version is now part of the jar’s name.

Importing the vehicles-1.0.jar

Now your vehicles.jar (now renamed to vehicles-1.0,jar) is Maven compliant. One of the main features of Maven is to handle (design time) dependencies of libraries. It does so by defining a Maven repository, where those libraries are stored. Those repositories are usually available online, either as public internet repositories or in the enterprise’s intranet. Moreover one can also define so-called “local repositories”, which one can use for testing purposes or alike. This is something I did in this example. I defined a “local” Maven repository for my jar(s) as a folder residing directly under my Java module. I named the folder “lib”.

And this repository I have then declared in the pom.xml of my Java module. In my case the section <repositories> was not there, so I had to create it.

 <repositories>
	<repository>
		<id>lib</id>
		<url>file:${project.basedir}/lib</url>
	</repository>
  </repositories>

Now before you import the vehicles-1.0.jar into the local repository, you need to create a (sub)folder structure, which will correspond to the Maven specific structure of your jar. This means that you need to create the folders /<groupId>/<atrifactId>/<version>, e.g. /company/vehicles/1.0:

Now all you have to do is import the vehicles-1.0.jar along with its pom.xml and the _remote.repositories files:

This folder structure is (of course) persisted on the Web IDE (XSA) host and you are one step away from concluding the process. The last step is configuring the (build) dependencies for the Java module. There is already a section <dependencies> in the pom.xml. One can see all the dependencies configured – for example there is the dependency on the servlet API, since I have created the Java module as “Simple Web Application” and the wizard had generated a “HelloWorld” servlet for me. I extended this section by the dependency for my vehicles-1.0.jar:

<dependency>
	<groupId>company</groupId>
	<artifactId>vehicles</artifactId>
	<version>1.0</version>
	<type>jar</type>
</dependency>

That’s it.

Now let’s test the setup. For that purpose I have coded few lines in my VehicleServlet. First I need an import statement for the class com.helper.vehicles.Car. Then I make an instance of Car and call the method setManufacturer() on that instance and set the manufacturer to “Ford”. (It’s just an example and the first brand that came to my mind – I don’t get any advertisement money or payments from Ford. You can set your own manufacturer). I finally write out the name of the manufacturer.

...
import com.helper.vehicles.Car;

@WebServlet("/hello")
public class VehiclesServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/plain; charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		
		Car car = new Car();
		car.setManufacturer("Ford");
		
		Connection conn = null;
		try {
			conn = getConnection();
		} catch (SQLException e) {
			throw new ServletException(e.getMessage(), e);
		}
		try (OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream(), "UTF-8")) {
			writer.write("Car manufacturer = " + car.getManufacturer());
			writer.write("\n\nJDBC connection available: ");
...

After saving all the files and building the MTA archive, I have invoked the Java application. The result is as expected. Remember that I haven’t coded/configured a (HANA) database connection.

 

Final remark

I have explained the process of integrating arbitrary JARs into the Web IDE of XSA. I took a single JAR as an example. If you have several Java archives, you could script the “mvn install” command, but the “import” in the Web IDE cannot be automated – at least not that I am aware of (please someone correct me, if I’m wrong). This is manual work and a drawback of this approach.

You can find details on Maven’s usage here (installing atrifacts, which were not built by Maven): http://maven.apache.org/plugins/maven-install-plugin/usage.html

I hope you will find this post helpful. We (the project team) gained this knowledge in the project previuosly mentioned. As we didn’t find anything on it in the official XSA documentation, I thought it was worth sharing.

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply