Skip to Content
Author's profile photo Ivan Mirisola

Spring Boot and SAP Cloud Platform: Neo

Background

Before we start using Spring or Spring Boot into a Java Application to be deployed no SAP Cloud Platform Neo we need to clear out some important information.

Don’t think about Neo Java Runtime as being the same as a Tomcat Server

Neo is based on a Tomcat container, but it isn’t the same as a full-blown Tomcat. A Tomcat Server is a Java EE system that contains more features that those provided by the Neo runtime. Furthermore, it allows additional configuration of the runtime that will demand administrator rights into its installation filesystem – such similar actions can only be accomplished by the SAP Cloud Cockpit or Neo Command Line Tools in the case of a Neo Application. Additionally, Neo will allow you to run your application in a single container. In other words, it will not allow you to deploy multiple WAR files to the same server instance. Since there are many conceptual differences between the two, we need to make some thoughtful considerations while porting a Tomcat application to Neo (will disclose those further down this blog).

A Spring application is defined differently in Neo, but not on Cloud Foundry

On a CF environment the only thing available to you is the Java build pack – which provides you with a complete Java Standard Edition runtime filesystem. Therefore, you must specify which JEE Container you wish to use for a Java application. Thus, the Spring Boot Starter Web package makes a lot of sense in the CF context. That is, you do not have to think about installing a Tomcat service since Spring Boot already provides one to you.

Consider the following

Avoid using the same Java libraries that are already included in the Neo SDK.

I highly encourage the usage of the Neo SDK to develop Java apps to be fully compatible with Neo. Keep in mind that each Neo SDK contains a stripped-down version of Tomcat or Web Profile and they all comply with the JEE standards. Therefore, you need to choose one SDK over the other to be able to use this or that specification. Check this out (https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/7613bd28711e1014839a8273b0e91070.html). Once you choose the SDK version, you may add libraries to your project.

Give precedence to the java libraries included in the Neo SDK

Unless you really know the internal consequences, excluding a jar file from the Neo SDK to allow another library version or even a complete re-implementation of the JEE specification by 3rd party libraries are discouraged. It is better to keep the usage of the libraries included in the Neo SDK and exclude the same implementation from other packages such as those provided by Spring Boot (i.e.: spring-boot-starter-web already contains an embedded Tomcat container which is basically the same thing Neo SDK is doing for you – the same goes for SFL4J). By doing so, you ensure that you are using same runtime environment that is to be found on SAP Cloud Platform while testing your application locally. Which in turn allows you to deploy your application less frequently into the cloud to make sure your application runs.

Configuring a Spring Application for Neo runtime

Create a simple Spring Boot application (I prefer using the Spring IDE to create my project but you could also be using Initializr (https://start.spring.io) or some other preferred method).

Make sure your project has the starter Web dependency:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

However, there is no need for the starter tomcat package, so it is safe to remove it now:

<!-- 		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency> -->

Add the following dependency to include the Neo Runtime for Java Web Tomcat 8 (make sure you define the SDK version in the properties session):

<dependency>
  <groupId>com.sap.cloud</groupId>
  <artifactId>neo-java-web-sdk</artifactId>
  <version>${sap.cloud.sdk.version}</version>
  <scope>provided</scope>
</dependency>

Here is an example for Java Web Tomcat 8 runtime (version 3.x is Tomcat 8):

<properties>
  <sap.cloud.sdk.version>3.54.23</sap.cloud.sdk.version>
</properties>

While running it locally as a Java application or Spring Application doesn’t present any issues. However, the java class loader in such cases are very different from the one used by SAP Cloud Platform to start your application. If you leave it at that, your project will not run in the cloud and will probably throw an exception like this:

ERROR org.slf4j.helpers.Util - SLF4J: Class path contains multiple SLF4J bindings.
ERROR org.slf4j.helpers.Util - SLF4J: Found binding in [jar:file:/tom8/repository/.archive/bin/logback-classic.jar!/org/slf4j/impl/StaticLoggerBinder.class]
ERROR org.slf4j.helpers.Util - SLF4J: Found binding in [jar:file:/wtpwebapps/coil.spring.app1/WEB-INF/lib/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
ERROR org.slf4j.helpers.Util - SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
17:03:39.138 [localhost-startStop-1] ERROR org.slf4j.helpers.Util - SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

It is clear here that the SLF4J is declared both by Spring Boot Starters and by the Neo runtime. Therefore, we need to remove dependency from our POM file, since there is no way to remove it from SCP itself. However, if we simply remove it the compilation may fail. Therefore we need to re-define it as being provided by something else in the POM. Here is how we do it:

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<!-- Some exclusions are necessary to make Spring Boot run on SCP. -->
			<exclusions>
				<exclusion>
					<groupId>ch.qos.logback</groupId>
					<artifactId>logback-classic</artifactId>
				</exclusion>
			</exclusions>			
		</dependency>
		<!-- Log requirements being provided by Neo SDK-->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<scope>provided</scope>
		</dependency>		
		<dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-core</artifactId>
			<scope>provided</scope>
		</dependency>

Running a Neo/Spring Application locally

Using the SCP Eclipse plugin you are able to create a server configuration to deploy your application directly via Eclipse.

First, download the SDK from https://tools.hana.ondemand.com/#cloud . Here I will be using the Java Web Tomcat 8 version.

Extract it into a folder of your choice.

Open Eclipse and select new à server from the context menu by right-clicking on the blank part of the servers tab

Select SAP Java Web Tomcat 8 (you will be prompted to select the installation folder which is the folder where you extracted the SDK)

 

 

After the server is created, double-click on it to open the configuration pane. Then open the Timeouts session and change the startup time to 120

Save the configuration file for this local server.

I am not going to teach you how to create a simple Spring Boot Application. Here I am using the simplest for of Spring Boot application (a simple servlet that says hello).

After you have your application tested in standalone mode you may add it as a web-module to your local Java Web Tomcat 8 server defined in Eclipse. Follow the steps below:

Once you start the local server the icon and text will change like following screen – stating: “Started, Synchronized”. To load all of the features specific to the Cloud Platform and start the Spring Boot application the whole process should take longer than the standard 45 seconds. This is the reason why we have changed to 120 seconds. You may need to increase this time when running the same process on a slower machine. It might also not be required at all because it depends on your machine’s performance.

Right-click the application and copy the application link to open in the external browser or open it directly on the integrated browser:

The result should be your application’s starting page, like so:

Differences between SCP and Local Runtime.

  • First, the Java Runtime will most likely not be the same. You may choose to run the application locally with Sun’s JRE while others may choose SAP’s JRE and it all may as well be on different revisions. On SCP it will also be true. Check the JVM that is available on each runtime. For instance: applications running on Java Web Tomcat 8 SDK will be installed on SCP with JVM 1.8.
  • Application’s URL running locally can be accessed via local IP, localhost or local machine. On SCP it will be composed of sub-account name and application id.
  • While running the application in standalone mode the application context isn’t defined. So, there is no suffix added to it. However, by deploying it on either the local server or on SCP a suffix will be added to it. The context name will be composed by the same name as the deployment unit name (WAR Filename). It is possible to deploy your app without this “add-context” – thus avoid the suffix altogether – by defining the WAR file name as ROOT.WAR, regardless of the application name you use during deployment.

 

Enjoy,
Ivan

Assigned Tags

      18 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo M M Sai Tharun Lakkoju
      M M Sai Tharun Lakkoju

      Hi Ivan,

      This is a very nice blog for understanding the differences between Neo Tomcat SDK and Apache Tomcat.

      We develop a lot of applications on the SAP Cloud platform and it's our daily routine to test our applications locally where we always increase the Server timeout to 120 seconds and sometimes even more. If we don't do the above increase, our servers always go timeout. The same application takes less than 20 seconds on plain Apache Tomcat. Even tomcat specifies every application should start ideally in less than 40 seconds. Even in your blog also you are suggesting to increase the timeout to 120 seconds.

      A couple of days back, we started analyzing why the server is taking a lot of time to start when we realized, the server itself is taking time to start without any application added in context.

      Please let us know what we can do for optimizing the server startup time.

      Author's profile photo Ivan Mirisola
      Ivan Mirisola
      Blog Post Author

      Hi M M,

      I am not in the product team so anything I say here is either empirical or rudimentary knowledge.

      From what I understand the local Tomcat implementation only provides the very basic functionality being as simple as it needs to be and yet very powerful when it needs to be by configuration and adding additional libraries onto to it.

      On the other hand, the local Tomcat installation provided by the SDK has loads of additional features - such as IdP integration, login page and other stuff that inherent to the SAP Cloud Platform (several libraries are loaded during boot time).

      Thus, if you really need to do some automation here (avoiding the need to wait for the app server to start and test your software), I'd suggest using the maven integration where it could start the web tomcat from the sdk, perform tests and die. Please take a look at the main project provided in the samples directory for a full example on how to perform tests under your pom.xml

      Best regards,
      Ivan

      Author's profile photo M M Sai Tharun Lakkoju
      M M Sai Tharun Lakkoju

      Thanks for the reply, Ivan. We will definitely try what you have suggested.

       

      Regards,

      Sai Tharun

      Author's profile photo Federico Jose Urones
      Federico Jose Urones

      Hi! Nice blog! Is it possible to connect a Spring Data JPA app (deployed on SHCP) to an on-premise Database? Thanks!

      Author's profile photo Ivan Mirisola
      Ivan Mirisola
      Blog Post Author

      Hi Frederico,

      Whenever you need to request data from a source that sits outside of SCP, you will need two things:

      • SAP Cloud Connector installed on the LAN (where the data source resides)
      • An HTTP resource that retrieves the data for you - probably the parts of your Java application that implement an OData service via Olingo/JPA.

      Cloud Connector will connect your LAN resources to an SCP Account. It contains all of the ACL to local resources and it registers the mapping of local hostnames to cloud virtual hostnames.

      Once you are done with that you can request the data directly from your Spring application.

      I wouldn't recommend you to make your Spring app interact with a remote database via JPA. I really don't think this would work as expected - the latency would not be quite as good a RESTful service or even something within the OData spectrum.

      Best regards,
      Ivan

      Author's profile photo Alfredo Semeco Blanco
      Alfredo Semeco Blanco

      Hi ivan thanks for the info

       

      Ivan I have a spring boot app. the app is conneted a DB on-premise SQL Server with SCC-SCP.  When i deploy the app and try to start get a exception:

       

      2019 07 12 21:12:53#+00#ERROR#org.apache.tomcat.jdbc.pool.ConnectionPool##anonymous#localhost-startStop-1#na#p2000687839trial#cloudspringbootsample#web##na#na#na#na#Unable to create initial connections of pool. com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host 192.168.50.52, port 1433 has failed. Error: "Connection timed out: no further information. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.".
      at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:227)
      at com.microsoft.sqlserver.jdbc.SQLServerException.ConvertConnectExceptionToSQLServerException(SQLServerException.java:284)
      at com.microsoft.sqlserver.jdbc.SocketFinder.findSocket(IOBuffer.java:2435)
      at com.microsoft.sqlserver.jdbc.TDSChannel.open(IOBuffer.java:635)
      at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2010)

      What do i need to do?, My DB its config yet in scp in conectivity. But the app never get the connection

       

       

      Author's profile photo Ivan Mirisola
      Ivan Mirisola
      Blog Post Author

      Hi Alfredo,

      TCP connections on SCC are actually a SOCKS5 proxy (please see: https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/c2461c31761b488c828e15b71263f3fd.html)

      So you have to make your application connect to the SOCKS5 proxy instead of the virual host name you provided on SCC.

      I've never done this specifically with Spring. But you might want to take a look at this blog:

      https://blogs.sap.com/2018/02/06/how-to-set-up-a-jdbc-connection-using-the-cloud-connector/

      Best regards,

      Ivan

      Author's profile photo Saroja Kuncha
      Saroja Kuncha

      Hi Ivan,

      Nice blog, thanks for sharing info. I have to create Spring Boot App and bind it to neo hana database Can you please help regarding this.

      Author's profile photo Ivan Mirisola
      Ivan Mirisola
      Blog Post Author

      Hi Saroja Kuncha,

      If you just want to create a shared schema to be used in java, just declared its usage in the web.xml as default:

       <resource-ref>
        <res-ref-name>jdbc/DefaultDB</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
       </resource-ref>

      Then bind your application to a new HANA shared instance. Here are the procedures required to do this (the blog is using ASE, but you could use HANA as well).

      If you have a HANA tenant, I would first create the database artifacts using Eclipse HANA Studio or Web-Based Development Workbench Tool. The reason for it is that these tools will provide the versioning and automatic change merge to your runtime artifacts. It does this by allowing you to model your database using design-time artifacts that will become runtime when activated. So you don't actually need to issue SQL commands for each change in the database.

      In JPA you have to disable the DDL generation. EclipseLink has a HANA dialect, so you can select it in your persistency.xml.

      Once you have the database runtime artifacts in place, you can use JPA to map to such entities.

      Best regards,
      Ivan

      Author's profile photo Pradeep V
      Pradeep V

      Hi,

       

      I am trying to create a simple spring boot project in neo account, i have a created a project through the spring initializer , when i add to server and trying to start the server, i am getting the following ,

      I just followed your blog to create a project and run in the neo account, can you please help me ?

      error:

       

      10:34:57.541 [main] ERROR java.lang.Throwable - at org.slf4j.bridge.SLF4JBridgeHandler.getSLF4JLogger(SLF4JBridgeHandler.java:198)
      10:34:57.541 [main] ERROR java.lang.Throwable - at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:293)
      10:34:57.541 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.log(Logger.java:738)
      10:34:57.541 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.doLog(Logger.java:765)
      10:34:57.542 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.logp(Logger.java:931)
      10:34:57.542 [main] ERROR java.lang.Throwable - at org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:180)
      10:34:57.542 [main] ERROR java.lang.Throwable - at org.apache.juli.logging.DirectJDKLog.debug(DirectJDKLog.java:103)
      10:34:57.542 [main] ERROR java.lang.Throwable - at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1172)
      10:34:57.543 [main] ERROR java.lang.Throwable - at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1137)
      10:34:57.543 [main] ERROR java.lang.Throwable - at org.slf4j.bridge.SLF4JBridgeHandler.getSLF4JLogger(SLF4JBridgeHandler.java:198)
      10:34:57.544 [main] ERROR java.lang.Throwable - at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:293)
      10:34:57.544 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.log(Logger.java:738)
      10:34:57.544 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.doLog(Logger.java:765)
      10:34:57.545 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.logp(Logger.java:931)
      10:34:57.545 [main] ERROR java.lang.Throwable - at org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:180)
      10:34:57.545 [main] ERROR java.lang.Throwable - at org.apache.juli.logging.DirectJDKLog.debug(DirectJDKLog.java:103)
      10:34:57.546 [main] ERROR java.lang.Throwable - at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1172)
      10:34:57.546 [main] ERROR java.lang.Throwable - at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1137)
      10:34:57.546 [main] ERROR java.lang.Throwable - at org.slf4j.bridge.SLF4JBridgeHandler.getSLF4JLogger(SLF4JBridgeHandler.java:198)
      10:34:57.547 [main] ERROR java.lang.Throwable - at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:293)
      10:34:57.548 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.log(Logger.java:738)
      10:34:57.548 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.doLog(Logger.java:765)
      10:34:57.548 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.logp(Logger.java:931)
      10:34:57.548 [main] ERROR java.lang.Throwable - at org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:180)
      10:34:57.549 [main] ERROR java.lang.Throwable - at org.apache.juli.logging.DirectJDKLog.debug(DirectJDKLog.java:103)
      10:34:57.549 [main] ERROR java.lang.Throwable - at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1172)
      10:34:57.549 [main] ERROR java.lang.Throwable - at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1137)
      10:34:57.549 [main] ERROR java.lang.Throwable - at org.slf4j.bridge.SLF4JBridgeHandler.getSLF4JLogger(SLF4JBridgeHandler.java:198)
      10:34:57.550 [main] ERROR java.lang.Throwable - at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:293)
      10:34:57.551 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.log(Logger.java:738)
      10:34:57.551 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.doLog(Logger.java:765)
      10:34:57.551 [main] ERROR java.lang.Throwable - at java.util.logging.Logger.logp(Logger.java:931)

       

       

      My Project Pom.xml is as follows:

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.2.2.RELEASE</version>
      <relativePath /> <!-- lookup parent from repository -->
      </parent>
      <groupId>com.example</groupId>
      <artifactId>SpringBootTestApp</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>war</packaging>
      <name>SpringBootTestApp</name>
      <description>Demo project for Spring Boot</description>

      <properties>
      <java.version>1.8</java.version>
      <sap.cloud.sdk.version>3.54.23</sap.cloud.sdk.version>
      </properties>

      <dependencies>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web-services</artifactId>
      </dependency>

      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <scope>runtime</scope>
      <optional>true</optional>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <scope>provided</scope>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      <exclusions>
      <exclusion>
      <groupId>org.junit.vintage</groupId>
      <artifactId>junit-vintage-engine</artifactId>
      </exclusion>
      </exclusions>
      </dependency>

      <dependency>
      <groupId>com.sap.cloud</groupId>
      <artifactId>neo-java-web-sdk</artifactId>
      <version>${sap.cloud.sdk.version}</version>
      <scope>provided</scope>
      </dependency>

      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <!-- Some exclusions are necessary to make Spring Boot run on SCP. -->
      <exclusions>
      <exclusion>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      </exclusion>
      </exclusions>
      </dependency>
      <!-- Log requirements being provided by Neo SDK -->
      <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <scope>provided</scope>
      </dependency>
      <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <scope>provided</scope>
      </dependency>
      <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <scope>provided</scope>
      </dependency>
      </dependencies>

      <build>
      <plugins>
      <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      </plugins>
      </build>

      </project>

       

       

      Thanks in advance :

      Pradeep

      Author's profile photo Ivan Mirisola
      Ivan Mirisola
      Blog Post Author

      Hi Pradeep,

      Apparently your pom is slightly off. I've managed to make the necessary changes to your pom so it works for a basic RestController (I've included the dependency for web-services from spring, but I didn't even test it).

      One problem was related to the neo SDK version - which isn't available on maven central any longer.

      Another issue was related to a duplicated dependency - but that was just a warning.

      Since you chose to use Spring Boot 2.2, you had to add Google's Json lib as well.

      Here is the modified pom file:

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
      	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      	<modelVersion>4.0.0</modelVersion>
      	<parent>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter-parent</artifactId>
      		<version>2.2.2.RELEASE</version>
      		<relativePath /> <!-- lookup parent from repository -->
      	</parent>
      	<groupId>com.example</groupId>
      	<artifactId>SpringBootTestApp</artifactId>
      	<version>0.0.1-SNAPSHOT</version>
      	<packaging>war</packaging>
      	<name>SpringBootTestApp</name>
      	<description>Demo project for Spring Boot</description>
      
      	<properties>
      		<java.version>1.8</java.version>
      		<sap.cloud.sdk.version>3.95.12</sap.cloud.sdk.version>
      	</properties>
      
      	<dependencies>
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-web-services</artifactId>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-devtools</artifactId>
      			<scope>runtime</scope>
      			<optional>true</optional>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-tomcat</artifactId>
      			<scope>provided</scope>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-test</artifactId>
      			<scope>test</scope>
      			<exclusions>
      				<exclusion>
      					<groupId>org.junit.vintage</groupId>
      					<artifactId>junit-vintage-engine</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>com.vaadin.external.google</groupId>
      					<artifactId>android-json</artifactId>
      				</exclusion>
      			</exclusions>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-web</artifactId>
      			<!-- Some exclusions are necessary to make Spring Boot run on SCP. -->
      			<exclusions>
      				<exclusion>
      					<groupId>ch.qos.logback</groupId>
      					<artifactId>logback-classic</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>org.springframework.boot</groupId>
      					<artifactId>spring-boot-starter-json</artifactId>
      				</exclusion>
      			</exclusions>
      		</dependency>
      
      		<!-- Neo SDK -->
      		<dependency>
      			<groupId>com.sap.cloud</groupId>
      			<artifactId>neo-java-web-api</artifactId>
      			<version>${sap.cloud.sdk.version}</version>
      			<scope>provided</scope>
      		</dependency>
      
      
      		<!-- Log requirements being provided by Neo SDK -->
      		<dependency>
      			<groupId>org.slf4j</groupId>
      			<artifactId>slf4j-api</artifactId>
      			<scope>provided</scope>
      		</dependency>
      		<dependency>
      			<groupId>ch.qos.logback</groupId>
      			<artifactId>logback-classic</artifactId>
      			<scope>provided</scope>
      		</dependency>
      		<dependency>
      			<groupId>ch.qos.logback</groupId>
      			<artifactId>logback-core</artifactId>
      			<scope>provided</scope>
      		</dependency>
      
      		<dependency>
      			<groupId>com.google.code.gson</groupId>
      			<artifactId>gson</artifactId>
      		</dependency>
      
      	</dependencies>
      
      	<build>
      		<plugins>
      			<plugin>
      				<groupId>org.springframework.boot</groupId>
      				<artifactId>spring-boot-maven-plugin</artifactId>
      			</plugin>
      		</plugins>
      	</build>
      
      </project>

      Best regards,
      Ivan

      Author's profile photo Pradeep V
      Pradeep V

      Hi Ivan,

       

      Thank you so much for the quick reply, and i just added the pom.xml to my project , but i am getting the same error again.

       

      any help would be great.

       

      Thank you,

      Pradeep

      Author's profile photo Ivan Mirisola
      Ivan Mirisola
      Blog Post Author

      Hi Pradeep V,

      Could you post the results from mvn build?

      Best regards,
      Ivan

      Author's profile photo Chris Paine
      Chris Paine

      Hi Ivan Mirisola I'm trying to convert an application I've been running on Neo for years over to Spring Boot.

      Whilst I think I've got the dependencies and build right, when I start the application on the SAP Neo Java Web Tomcat 8 server my actual application doesn't start. All the Web resources are available - but none of the server side components start.

      I have created an SpringBootServletInitalilizer:

      @SpringBootApplication
      public class Application extends SpringBootServletInitializer {
      
      	@Override
      	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
      		return application.sources(Application.class);
      	}
      
      	public static void main(String[] args) {
      		SpringApplication.run(Application.class, args);
      	}
      
      }

      and my pom.xml seems to mirror the one above fairly closely

      I can start the application using "run Java application" option choosing the above application, which then triggers reading all the other components and config in my application - although promptly the application fails when it attempt to do a jndi lookup  to find the environment variable ("jdbc/DefaultDB") defined in my web.xml.

      Can you think of anything I might have missed?

       

      Many thanks for your help.

       

      Chris

       

      Author's profile photo Ivan Mirisola
      Ivan Mirisola
      Blog Post Author

      Hi Chris Paine,

      I believe the tomcat 8 runtime doesn't have any support JPA - if that's what you want to use here.

      You might need to switch from tomcat 8 runtime to web profile:

      https://help.sap.com/viewer/ea72206b834e4ace9cd834feed6c0e09/Cloud/en-US/f177a15bab8c47168cbcf471b7726f78.html

      But it is hard to be sure unless you provide some error messages from the logs.

      Do you have a trace or log error message from when you make the calls to jndi?

      Best regards,
      Ivan

      Author's profile photo Chris Paine
      Chris Paine

      Hi Ivan,

      I've been using Tomcat 8 and JPA for years - it's fine - I use spring data. The jndi lookup isn't the issue (that's because I try to run it as an app but without the embedded tomcat server (marked as provided) so it fails) it's just getting the app to actually start when I've reconfigured it to use spring boot.

      My problem is - there are no error messages - the server starts perfectly - it just doesn't run the app... I can see my app is deployed to the tomcat server - This is the frustrating bit. If I do something like configure the dependencies in the app to have issues - like conflicting versions of the logger - then the server doesn't start and I get error messages. So I'm pretty sure that my libraries and dependencies are getting deployed, but the actual servlets - they aren't getting initialised, and I'm not sure why! It's like tomcat isn't launching/finding the main app class and I have no idea why!

      any ideas most happily received.

      Thanks,

      Chris

      Author's profile photo Chris Paine
      Chris Paine

      Hi Ivan,

       

      I realised I needed to move the code from my configuration class implementing the WebApplicationInitializer into the new class implementing the SpringBootServletInitializer.

      But still, not getting the application logic started - think it may well be the JNDI lookup seeing other have had similar issues with Spring Boot in past...

       

      Author's profile photo Ivan Mirisola
      Ivan Mirisola
      Blog Post Author

      Hi Chris,

      The best to try to find out what is going on is to run it locally in Eclipse - by creating a server configuration based on the Web Tomcat 8. This will reproduce the environment your application will find at the Neo environment.

      If you want I could have a look at your project if you are willing to share in github with me.

      Best regards,
      Ivan