javaazurecloudgrizzly

how to deploy jar file to azure?


I've created a RESTFul service using grizzly and google guice. I am able to access it running on the command line:

c:\Java\src\options\console>java -jar target\ServerConsole-V1.jar

Nov 28, 2017 3:18:01 PM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started. 
web server started successfully at http://localhost:8080/ 
...press any key to stop the process

Now I want to deploy this service to the cloud. I found articles about deploying a SpringBoot apps and creating webjobs with jar files, but none of these apply to how my app is working.

Am I going to have to re-engineer the webserver (to spring boot) or can I deploy this as is? if so, how?

thnx, Matt

EDIT: I've followed Jay steps below. I created a web.config as

<?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=8080 -jar &quot;%HOME%\site\wwwroot\ServerConsole-V1.jar&quot;">
    </httpPlatform>
  </system.webServer>
</configuration>

When I try to access a RESTFul API using either browser or PostMan, I get time out errors. How can I diagnosis this?


Solution

  • You don't have to rearchitect your app, grizzly will run just fine, the only problem is that the documentation is not clear enough.

    The run.jar tutorial is helpful but there are two key points that is missing in order to deploy grizzly based apps.

    I'm using similar maven configuration as the configuration used to deploy Spring boot applications.

    <plugin>
      <groupId>com.microsoft.azure</groupId>
      <artifactId>azure-webapp-maven-plugin</artifactId>
      <version>1.9.0</version>
      <configuration>
        <schemaVersion>V2</schemaVersion>
        <resourceGroup>Your_apps_resource_group_name</resourceGroup>
        <appName>Your-app-name</appName>
        <region>eastus2</region>
        <pricingTier>F1</pricingTier>
        <runtime>
          <os>linux</os>
          <javaVersion>jre8</javaVersion>
          <webContainer>jre8</webContainer>
        </runtime>
        <!-- Begin of App Settings  -->
        <appSettings>
         <property>
           <name>JAVA_OPTS</name>
           <value>-Dserver.port=80  -Djava.net.preferIPv4Stack=true</value>
         </property>
        </appSettings>
        <!-- End of App Settings  -->
        <deployment>
         <resources>
           <resource>
             <directory>${project.basedir}/target</directory>
             <includes>
                <include>*.jar</include>
             </includes>
           </resource>
         </resources>
       </deployment>
     </configuration>
    </plugin>
    

    The key here is the JAVA_OPTS property value

    -Dserver.port=80  -Djava.net.preferIPv4Stack=true
    

    The application will be running on an Azure container that assigns the server port randomly when it starts, so the grizzly's regular 8080 won't work 99.9999% of times.

    In order to set up the port you need to get the system property

    public static void main(String[] args) throws IOException, ServletException {
      String port = "8080";
      if (!Objects.isNull(System.getProperty("server.port"))) {
        port = System.getProperty("server.port");
      }
      System.out.println("Using server port " + port);    
      String host = "0.0.0.0";
    
      final String baseUri = String.format("http://%s:%s/", host, port);
      startServer(baseUri);
      System.out.println(String.format("Jersey app started with WADL available at "
        + "%sapplication.wadl%nHit enter to stop it...", baseUri));
      System.out.println(String.format("Jersey app started with WADL available at "
        + "%sswagger.json%nHit enter to stop it...", baseUri));
    
    }
    

    The other key here is that in order to run inside the container and bind the IP address grizzly needs to start on 0.0.0.0 instead of local host(What is the difference between 0.0.0.0, 127.0.0.1 and localhost?)

    The start server method receives the base URI instead of using the private static one as follows.

    public static HttpServer startServer(final String baseUri) throws ServletException {
    
      WebappContext webAppContext = new WebappContext(
        "GrizzlyContext", "/");
    
      HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create(baseUri));
      CLStaticHttpHandler staticHttpHandler
            = new CLStaticHttpHandler(Main.class.getClassLoader(),"/www/");
      server.getServerConfiguration().addHttpHandler(staticHttpHandler,"/");
      webAppContext.deploy(server);
      return server;
    }