Hot questions for Using Azure in jar

Question:

I'm having trouble getting a Spring Boot API to work on an Azure app service. I've followed the Microsoft guide on https://docs.microsoft.com/en-us/java/azure/spring-framework/deploy-spring-boot-java-web-app-on-azure but having no luck so far.

The application does start (I can see the app boot up in the log file) but http requests to the app service url always end in a timeout.

I've read that Azure app services only pick up embedded tomcat servers that run on port 80 or 8080, but had no luck with that as well.

The app is deployed in the www root and an appropriate web.config is deployed as well.

I've tried running the App Service with and without an application server (Tomcat and Jetty, that is not needed because the server is embedded in the application), but both approaches failed.

Am I missing some other configuration part? Or could this be related to the type of plan I'm using on azure? Maybe some issue with the resource?

Any pointers?

Thx,

Bert


Answer:

Please use following steps given by spring and azure community to deploy spring boot app on azure:

1) Go inside of your app folder where you have pom file and run

make sure following plugins should be in 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>gs-spring-boot</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- tag::actuator[] -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- end::actuator[] -->
        <!-- tag::tests[] -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- end::tests[] -->
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
        <maven.build.timestamp.format>yyyyMMddHHmmssSSS</maven.build.timestamp.format>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>com.microsoft.azure</groupId>
                <artifactId>azure-webapp-maven-plugin</artifactId>
                <version>0.1.5</version>
                <configuration>
                    <authentication>
                        <serverId>azure-auth</serverId>
                    </authentication>
                    <resourceGroup>maven-plugin</resourceGroup>
                    <appName>maven-web-app-${maven.build.timestamp}</appName>
                    <region>westus</region>
                    <javaVersion>1.8</javaVersion>
                    <deploymentType>ftp</deploymentType>
                    <stopAppDuringDeployment>true</stopAppDuringDeployment>
                    <resources>
                        <resource>
                            <directory>${project.basedir}/target</directory>
                            <targetPath>/</targetPath>
                            <includes>
                                <include>*.jar</include>
                            </includes>
                        </resource>
                        <resource>
                            <directory>${project.basedir}</directory>
                            <targetPath>/</targetPath>
                            <includes>
                                <include>web.config</include>
                            </includes>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Note : Make sure you have created web app on azure with same name as maven-web-app-${maven.build.timestamp}

Now create file on root with name "web.config" and add your jar in web.comfig

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers>
            <add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
        </handlers>
        <httpPlatform processPath="%JAVA_HOME%\bin\java.exe"
                      arguments="-Djava.net.preferIPv4Stack=true -Dserver.port=%HTTP_PLATFORM_PORT% -jar &quot;%HOME%\site\wwwroot\azure-rest-example-app-0.1.0.jar&quot;">
        </httpPlatform>
    </system.webServer>
</configuration>

Now open azure CLI and run following commands

  • mvn clean package
  • mvn spring-boot:run

Make sure app is working fine on local.

Now use following commands if you have multiple account associated with your id

  • az login

  • az account list

  • az account set --subscription XXX-XXX-XXX-XXXXXXXXXXXX

Now you need to create "Service Principals in Microsoft Azure"

1) Open a terminal window.

2) Sign into your Azure account with the Azure CLI by typing az login

3) Create an Azure service principal by typing az ad sp create-for-rbac --name "vaquarkhan" --password "yourpassword" (vaquarkhan is the user name and yourpassword is the password for the service principal).

az ad sp create-for-rbac --name "app-name" --password "password"

NOTE :if you getting error need to change settings---> here

"azure.graphrbac.models.graph_error.GraphErrorException: Guest users are not allowed to perform this action."

if success

Azure should print out a JSON response resembling this:

{
   "appId": "XXX-XXXX-XXX-XXX-XXXX",
   "displayName": "vaquarkhan",
   "name": "http://vaquarkhan",
   "password": "yourpassword",
   "tenant": "YYY-YYYY-YYY-YYY-YYYY"
}

Configure Maven to use your Azure service principal

1) Open your Maven settings.xml file in a text editor (usually found at either /etc/maven/settings.xml or $HOME/.m2/settings.xml).

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository/>
  <interactiveMode/>
  <usePluginRegistry/>
  <offline/>
  <pluginGroups/>

  <servers>
   <server>
     <id>azure-auth</id>
      <configuration>
         <client>ur key</client>
         <tenant>ur tenant</tenant>
         <key>YOUR PASSWORD</key>
         <environment>AZURE</environment>
      </configuration>
   </server>
</servers>


  <proxies/>

  <profiles>
    <profile>
      <id>hwx</id>
      <repositories>
        <repository>
          <id>hwx</id>
          <name>hwx</name>
          <url>http://nexus-private.hortonworks.com/nexus/content/groups/public/</url>
        </repository>
      </repositories>
    </profile>
  </profiles>


  <mirrors>
    <mirror>
      <id>public</id>
      <mirrorOf>*</mirrorOf>
      <url>http://nexus-private.hortonworks.com/nexus/content/groups/public/</url>
    </mirror>
  </mirrors>

  <activeProfiles/>
</settings>

2) Add your Azure service principal settings from the previous section of this tutorial to the collection in the settings.xml file as shown below:

<servers>
   <server>
     <id>azure-auth</id>
      <configuration>
         <client>aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa</client>
         <tenant>tttttttt-tttt-tttt-tttt-tttttttttttt</tenant>
         <key>pppppppp</key>
         <environment>AZURE</environment>
      </configuration>
   </server>
</servers>

3) Save and close the settings.xml file.

Build and deploy your app to Azure

1) run following command

  • mvn azure-webapp:deploy
  • When your web app has been deployed, visit the Azure portal to manage it. It will be listed in App Services.

  • Click on the application. From there, the publicly-facing URL for your web app will be listed in the Overview section

  • Determining the URL for your web app You can click on this link to visit the Spring Boot application and interact with it.

Azure maven plugin doc

Note : The website name has to be globally unique and its generated using app name , make sure name should be unique.

Question:

I have an application developed in java. I have exported it to an executable jar and I would like to upload it to azure so that it runs with a certain schedule. Until now it has been impossible for me to know how it is done. I have done a web service with eclipse and if it is easy to deploy it in azure and make it work but not executable. Can someone tell me how it is done?


Answer:

It sounds like you want to run an executable jar file with a time trigger on Azure. The simple way is to deploy your jar file as a WebJob on Azure WebApp. Here is the steps to do it as below.

  1. Create a .bat file named run.bat and write the follow commands as below.

    set JAVA_HOME=D:\Program Files (x86)\Java\jdk1.8.0_172
    set CLASSPATH=.;%JAVA_HOME%\lib
    set PATH=%JAVA_HOME%\bin;%PATH%
    java -jar <your jar file name>.jar
    
  2. Compress the run.bat file and your jar file to a zip file, then to deploy it with Scheduled trigger and a CRON Expression value on Azure portal.

Then, you can start it on Azure portal, and to see the running logs via Logs button.

Note: for more information about CRON Expression or others, please see the section CRON expressions of the offical tutorial Run Background tasks with WebJobs in Azure App Service.

Question:

I build a Spring Boot jar on Jenkins, and upload through FTP to Azure, but since the app is still running, and I get error below. What is the recommended way to handle this on azure? I assume I somehow should shut the server down before uploading the jar, and start it again after upload.

..........
FTP: Connecting from host [ip-172-20-20-20]
FTP: Connecting with configuration [Back-End-Azure-FTP] ...
FTP: Disconnecting configuration [Back-End-Azure-FTP] ...
ERROR: Exception when publishing, exception message [Could not write file. Server message: [550 The process cannot access the file because it is being used by another process. 
]]
Build step 'Send build artifacts over FTP' changed build result to UNSTABLE
Notifying upstream projects of job completion
Finished: UNSTABLE

Thanks in advance


Answer:

One way of implementing this can be using spring actuator. They are documented here . They have a lot of handy instrumentation API and shutdown is one of the ways. You can drop in a simple POM dependency and that should do it (also enable shutdown in application yaml)

Before you run your FTP part , you will have to execute a post call through cURL to stop it and then deploy the new version package.

Question:

I noticed that Azure's Java SDK has several maven dependencies which seem to be targeting the same thing, for instance, the following artifact ids:

  • azure-management-storage:0.8.0
  • azure-mgmt-storage:0.8.0
  • azure-svc-mgmt-storage:0.8.0

It's the same with network and compute.

Does anyone know what's the difference between those?

Thanks!


Answer:

I suggest you to use azure-svc-mgmt-storage jar.

I reviewed the maven repository page of "azure-management-storage" http://mvnrepository.com/artifact/com.microsoft.azure/azure-management-storage. Microsoft has renamed the artifact to "azure-svc-mgmt-storage". It's the same with network and compute.

For azure-management-storage, azure-mgmt-storage and azure-svc-mgmt-storage, I recommend you refer to this document: https://github.com/Azure/azure-sdk-for-java/wiki/Azure-SDK-for-Java-Features

Best Regards.

Question:

I have a project setup from the code here: Azure Storage Java in intellij. I used the option 3 - downloaded the source code and set it up as a maven based project in Intellij. when I try to give the make command I get lot of errors - null pointer exceptions I need to create a jar file out of it. What am I missing in the setup/ jar generation


Answer:

I tried to reproduce the issue thru redo the process of make module from Azure Storage Java source code by using IntelliJ IDEA Community Edition 15, but failed to got any errors.

There are my steps below:

  1. Download the source code using Git: git clone https://github.com/Azure/azure-storage-java.git.

  2. Startup the IntelliJ and choose the option - 2 "Import Project", see below:

Also, you can merge two steps above to choose the option - 3 "Check out from Version Control" and select the downloaded source code directory.

  1. select "Maven" as "import project from external model", click "Next" button, see below:

  1. Continue to click "Next" buttons until "Finish" button, click it to Open the project window.

  2. Right click on the prject name and select "Make Module" to click, see below:

  1. Get the target directory without any errors, see below:

If you need the artifact jar file of Azure Storage Java, you can directly download it from the project maven repository http://mvnrepository.com/artifact/com.microsoft.azure/azure-storage/4.0.0.

Question:

I've got myself an Azure Web App Service and a SQL database to go with it. I'm using Azures Intellij plugin to "Run On Web App". Issue is, it doesn't run anything, however it does put the jar in the folder:

Connecting to FTP server...
Uploading artifact to: /site/wwwroot/ROOT.jar ...
Uploading successfully...
Start Web App...
Logging out of FTP server...
Deploy successfully!

I then, using console try to run the ROOT.jar by using java -jar ROOT.jar, but I get the error message

Java is not recognised as an internal command or external command

In the webapp application settings I have Java Version: Java 8 So I'd assume it'd give me the ability to run java, but this has just made me question the way I'm doing it. Am I deploying the app wrong?


Answer:

It sounds like your SpringBoot project lacked a web.config file which will be deployed at the path wwwroot for helping to handle your ROOT.jar.

Here is a sample web.config file for SpringBoot runnable jar.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
    </handlers>
    <httpPlatform processPath="%JAVA_HOME%\bin\java.exe"
        arguments="-Djava.net.preferIPv4Stack=true -Dserver.port=%HTTP_PLATFORM_PORT% -jar &quot;%HOME%\site\wwwroot\ROOT.jar&quot;">
    </httpPlatform>
  </system.webServer>
</configuration>

As above, it comes from my answer of a similar SO thread Deploying Springboot to Azure App Service which you can refer to.

Question:

I am developing a java server-like application (though it is not a server itself, more like a bot for social network) and I decided to use Azure virtual machine to deploy the app on. So I've chosen Ubuntu virtual machine. I successfully uploaded .jar file on server, connected to it with Bash shell for Windows and SSH (as described in manual for Azure). Then I am able to launch my file with java -jar server.jar and it works. But the problem is that when I close the shell on my home computer, the app shuts down on the server too. So my question is how to launch .jar file in the way where it won't exit once I close SSH session?


Answer:

Run the command in the background with nohup:

nohup java -jar server.jar &

Question:

I was able to run metabase.jar on my machine (W10), and now I need to try on Azure, because it's where I have SQL Server.

Metabase.jar: metabase.com/start/

I couldn't do it by myself (closure and jetty are new to me).

On Azure, I tried:

  • Create a web app;
  • Set to Java 8 and Jetty 9.1;
  • Failed to run metabase.jar.

Answer:

Based on my understanding, I think you want to deploy the metabase.jar file as a web application on Azure WebApps like on local. Then I followed the article to upload the metabase.jar file into the directory wwwroot/bin which I created it via Kudu console and create & configure a wwwroot/web.config below to start up the app.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers>
            <add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
        </handlers>
        <httpPlatform processPath="%ProgramW6432%\Java\jdk1.8.0_60\bin\java.exe" arguments="-Djava.net.preferIPv4Stack=true -Dport.http=3000 -jar &quot;%HOME%\site\wwwroot\bin\metabase.jar&quot;" stdoutLogEnabled="true" startupRetryCount='10'>
        </httpPlatform>
    </system.webServer>
</configuration>

The result of deployment is that I can't startup it completely without any error. It seems that the app constantly restart by Azure WebApp because of some reasons, such as some resource exceeded quotes not enough memory or unable to connect to Metabase DB. While I scaled up the tier for my testing webapp from small to large, the issue still occured. Please see the figures below.

So I think that it seems to deploy metabase on Azure only via using Docker or Virtual Machine. Hope it helps.