Hot questions for Using Azure in tomcat

Question:

I have created a Microsoft azure web app and configured java version 8 and tomcat latest available. As per their documentation , I have uploaded my WAR file to d:\home\site\wwwroot\webapps\ROOT .

Screenshot of MY Directory

wen iam trying to access, giving me a 404 error.Please help me to fix this


Answer:

as documentation say :

you can upload your application by placing your WAR in the webapps folder.

in tomcat's webapp folder you copy war files, tomcat detects the presence of one of those files and unzip it to a folder corresponding to the name you chose for your file, so if you copy toto.war to

$TOMCAT_HOME/webapps/

after tomcat deployed your war file the folder will look like

$TOMCAT_HOME/webapps/toto.war
$TOMCAT_HOME/webapps/toto  (folder being the unzipped version of your file)

ROOT folder is just a special case of that for the webapplication that is served without using a context.

Question:

I created a java-based website on Azure, and selected tomcat as container when used "CUSTOM CREATE", then there is an empty website ready and I can upload WAR files using ftp but not able to touch tomcat files. I need change the heap size of JVM, how to do that?


Answer:

please see http://azure.microsoft.com/en-us/documentation/articles/web-sites-java-custom-upload/ - see section "Tomcat". You could either upload your own tomcat as mentioned in this link OR you can just configure httpPlatform section in your web.config to override the JAVA_OPTS with any jvm parameter you want.

Thanks.

Question:

I have an Azure App Service running Tomcat 8.5 and can't seem to figure out how to do a thread dump. jstack is not recognized in the Console nor the DebugConsole.


Answer:

On Azure App Service, all popular versions of Java had been installed at the path D:\Program Files (x86)\Java. Take version 1.8.0u73 as example, please see the figure below.

You can command set PATH=D:\Program Files (x86)\Java\jdk1.8.0_73\bin;%PATH% to add Java tools to the environment temporarily via the Kudu console tool. Then, the jstack tool is available in the current Kudu session.

Question:

We have recently upgraded our spring boot dependency from 1.3.5 to 1.5.8; on deployment to the Azure hosted Tomcat container, we noticed that the deployments don't start up correctly. Upon further examination of the catalina logs:

org.apache.catalina.startup.ExpandWar.deleteDir could not be completely deleted. The presence of the remaining files may cause problems.

We are aware that the issue can be corrected by adding antiResourceLocking="true" to the context.xml, however since we want to keep our platform as a service, we do not have access to modify this configuration.

Is there a way of setting this configuration in web.config or in some other manner on azure, while maintaining the tomcat container as a service?


Answer:

So the solution to this problem is to place a context.xml into src/main/webapp/META-INF, as explained here.

The solution is detailed in the Context Container section of Apache Tomcat Configuration reference.

Since we have read access to D:/, I just coppied the context.xml from the Tomcat installation there and modified it by changing <Context antiResourceLocking="true">.

This way, we did not need to install Tomcat from the marketplace or pack it into the war.

Question:

I am having a trouble with deploying on Azure's Tomcat servlet container. I connect to created web-app space with FTP copying the war file to the correct folder.

myWebApp

I have successfully deployed a Spring MVC simple web application on Azure. The URL pattern is below and the both work as expected:

  • http://myWebApp.azurewebsites.net/myWebApp Deployed on Azure Tomcat
  • http://localhost:8080/myWebApp Deployed on local Tomcat

The key file is web.xml below:

<web-app ... xsd schemas ... >

    <display-name>myWebApp</display-name>

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>... not important ...</context-param> 
    <listener>... not important ...</listener>
</web-app>

myWebService

Well, the problem comes when I want to deploy a simple web service the same way and see its content.

I have decided to use jersey library. Here is the only sample class:

@Path("Sample")  
public class Sample {
    @GET  
    @Path("/")  
    @Produces(MediaType.TEXT_XML)  
    public String Method() {
        return "<tag>" + 123 + "</tag>";  
    }
}

After clean install and running on local Tomcat server on URL http://localhost:8080/myWebService/Sample, it correctly gives me the XML <tag>123</tag>".

I hopefully deployed on Azure the same way like the previous myWebApp and tried to run on the URL http://myWebService.azurewebsites.net/myWebService. It gaves me the 404 error instead, saying that the requested resource is not available.

Here is the web.xml for sure:

<web-app ... xsd schemas ... >
    <display-name>myWebService</display-name>
    <servlet>
        <servlet-name>Jersey REST Service</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>nch.webservices</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey REST Service</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

What am I missing and I do wrong? I have noticed the difference between both web.xml files in url-pattern that:

  • myWebApp uses /
  • myWebService uses /*

When I use <url-pattern>/</url-pattern> on myWebService, then it either doesn't work on localhost. Thanks for help. Feel free to ask for more info if needed (wanted to make the question as short as possible).


Answer:

According to your description & codes, I tried to reproduce your issue of the myWebService successfully. The issue 404 of accessing http://myWebService.azurewebsites.net/myWebService of myWebService was caused by the url-pattern not match the Method url of class Sample, please see the explainations below.

  1. In the class Sample, the class annotation @Path("Sample") and the method annotation @Path("/") for method Method means that the accessable url for the method Method of the class Sample in myWebService project is http://myWebService.azurewebsites.net/myWebService/Sample/.
  2. The url-pattern value / means only match the url http://myWebService.azurewebsites.net/myWebService/.

There are two solutions for your case.

  1. Recommended. Using the wildcard /* instead of / for url-pattern and access the url http://myWebService.azurewebsites.net/myWebService/Sample/. And suggestion that change the class annotation @Path("Sample") to @Path("/Sample") for reading and understanding.

  2. Only change the class annotation @Path("Sample") to @Path("") or @Path("/") if not change url-pattern, but any path annotations for other classes will not be matched.

Question:

I'm using a JNDI ressource in Tomcat8 for connecting to a MS-SQL database (Azure). Randomly I experience Connection closed exception, eventually preceeded by Connection peer reset events. When this happens, the service is dead (running into Connection closed for every request) and restarting the tomcat (redploying) is the only chance to get it up again.

On my way trying to solve this I double(triple)-checked every method for unclosed connections, I assure that every connection is opened as try-with-ressource.

Currently I'm trying to get a better understanding about JNDI ressources and the connection pooling, I'm asking what is the preferred pattern to implement a service class which is injected into other services. E.g. questions are

  1. Where should the DataSource be allocated by calling ctx.lookup()? On method level or class scope? E.g. when using the hk2 @Service annotation it seems that a service is instantiated only once and not per request. Currently ctx.lookup() is invoced once (in the constructor) and the DataSource is stored in a class field and later on accessed by the methods using this.dataSource. Does this make sense ? Or should the DataSource be retrieved on every request (=method call)

  2. How can I verify the execution of several options of the DataSource, e.g. testOnBorrow and removeAbandoned (see complete configuration below) are executed correctly? There is an option logAbandoned but I can not see anything in my logs. Where should this appear anyhow? Can I somehow specifiy a certain log level for the pool? I only found org.apache.tomcat.jdbc.pool, but this class seems only to be called when creating the pool (at least this is the only moment when logs appear, even on level FINEST).

  3. Are there general patterns which I'm not aware of?

Here my current configuration:

<Resource name="jdbc/mssql"
          auth="Container"
          type="javax.sql.XADataSource"
          driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
          username="***"
          password="***"
          url="jdbc:sqlserver://***.database.windows.net:1433;database=***;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;"
          factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
          removeAbandonedOnBorrow="true"
          removeAbandonedTimeout="55"
          removeAbandonedOnMaintenance="true"
          timeBetweenEvictionRunsMillis="34000"
          minEvictableIdleTimeMillis="55000"
          logAbandoned="true"
          validationQuery="SELECT 1"
          validationInterval="34000"
        />

Thx, gapvision


Answer:

Gapvision, you can check this link - What is the good design pattern for connection pooling?

Probably, you would want to go with the object pool pattern. Hope this helps !!

Question:

I can see Azure currently only supports Java 7 and Tomcat 7 or Jetty 9.1. As for the development of a system, the customer is considering Azure as an option for hosting the Java application. The application will be written in Java 8. Does anyone know if Microsoft has any plans for updating their Tomcat server to Tomcat 8? Amazon already got this in November last year, so I would assume Microsoft would not be waiting too long. Does anyone know if Microsoft has any "official" plans on upgrading it so I don't have to buy an entire VM just for a web app? (Or use Java 7 for that matter)


Answer:

There is no official statement from Microsoft. But Microsoft are flexible enough and have envisioned your requirement. You can use entirely your own Java build if you want, along with your own build of Tomcat. Of course, the builds have to be compatible with Windows operating system.

For detailed instructions on how to change Java and Tomcat versions, refer to the following article: http://azure.microsoft.com/en-us/documentation/articles/web-sites-java-custom-upload/

Question:

I tried uploading files to the server deployed in azure web app service. In local it's working fine and when it comes to azure it throwing some exception. FileSizeLimitExceededException.

This upload service is developed in JAVA Spring boot version 1.5.8

Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes

spring:
  http:
    multipart:
      max-file-size: 10MB
      max-request-size: 100MB
      enabled: true

Also tried some @Bean entity configuration also. It doesn't help me out.

Tried web.config with custom server.xml file specifying maxPostSize.

I need to set the maximum upload limit to 10MB.


Answer:

I see you were using application.yml instead of application.properties as the configuration file for your spring-boot app. However, I'm worried about there is not a application.properties file in your project. And as the section [24.6 Using YAML instead of Properties]1 of the Spring offical document for version 1.5.8 said,

YAML is a superset of JSON, and as such is a very convenient format for specifying hierarchical configuration data. The SpringApplication class will automatically support YAML as an alternative to properties whenever you have the SnakeYAML library on your classpath.

[Note] If you use ‘Starters’ SnakeYAML will be automatically provided via spring-boot-starter.

Therefore, there must be a SnakeYAML library in your project, whatever directly add a jar file or configure the maven pom.xml file, if without application.properties.

Question:

Everything is running well when debugging my webapp at localhost, but when deploying it to to server (Microsoft Azure, OS:Ubuntu 14.04 tomcat7+apache ), the jcaptcha servlet cannot be found, and it throws Exception as "java.lang.NoClassDefFoundError: Could not initialize class "

type Exception report

message Servlet execution threw an exception

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Servlet execution threw an exception
    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:88)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
root cause

java.lang.NoClassDefFoundError: Could not initialize class com.tjw.hrmanage.util.jcaptcha.CaptchaServiceSingleton
    com.tjw.hrmanage.util.jcaptcha.JcaptchaServlet.doGet(JcaptchaServlet.java:40)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:88)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.52 (Ubuntu) logs.

Answer:

This is because your app in ubuntu can not find the corresponding jar file. You can add this class's jar file to /lib and add reference for this jar in 'build path' in eclipse and then redeploy your project to azure again.