Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot app deployed to Glassfish is giving strange results

As mentioned here, I am having a heck of a time getting my small Spring-Boot project to deploy "correctly" to Glassfish. It runs fine using the embedded Tomcat, but once I try and move it into my organization's environment (Glassfish 3.1.2) I get some strange behavior.

Thinking it was my code, I reverted to the time-tested "Hello World"-approach and built a super-basic app following this tutorial on Spring's blog.

I did make a few very minor deviations as I went along but nothing that should have affected the app like this at all.

The only major deviation I made was that I found I could not exclude "spring-boot-starter-tomcat" from "spring-boot-starter-web" -- when I tried to that, I got 2 errors in the STS "Markers"-tab:

The project was not built since its build path is incomplete. Cannot find the class file for javax.servlet.ServletContext. Fix the build path then try building this project    
The type javax.servlet.ServletContext cannot be resolved. It is indirectly referenced from required .class files    Application.java    

If I cleaned the STS project, then ran Maven Clean, Update, Install the Install goal gave the following error:

Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project test: Compilation failure [ERROR] /Users/brandon_utah/Utah Development/sts_workspaces/NidTools Rebooted/test/src/main/java/test/Application.java:[13,8] cannot access javax.servlet.ServletException [ERROR] class file for javax.servlet.ServletException not found

So what I did instead was include this dependency (which I found mentioned in several other SpringBoot resources):

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

In this deployed fine to the embedded Tomcat and it did deploy to my Glassfish (local install) -- but with a whole bunch (about a half-dozen) errors similar to this one:

2014-04-03T16:23:48.156-0600|SEVERE: Class [ Lorg/springframework/jdbc/datasource/embedded/EmbeddedDatabase; ] not found. Error while loading [ class org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration ]

Most of them are SEVERE, but I am also getting a few with a WARNING:

2014-04-04T06:57:35.921-0600|WARNING: Error in annotation processing: java.lang.NoClassDefFoundError: org/springframework/batch/core/configuration/annotation/BatchConfigurer

Except that I'm not referencing any of these missing classes anywhere in my project (other than what might be referenced by Spring Boot itself).

Also, the app doesn't quite work as expected. If I hit the RestController, I do get my page rendered as I expect -- but if I put any sort of System.out or Logger.log statement in the controller's method, that line of code seemingly never gets executed; by all appearances, it just gets skipped.

To demonstrate this problem, in my sample app's RestController I created a static counter. Then in the GET-/ method I increment that counter and System.out.println it's value. I also return the value as part of the Response.

And again, from a user's perspective, it seems to be working: the screen renders "Hello World" and in parentheses it shows the counter's value. I refresh the window, the counter increments. But nothing in the STS Console. And if I navigate to the Glassfish log for the app, nothing there either. Nothing. Nada. Zip. From what I can tell, something is mysteriously eating any attempt to log anything.

To add to the mystery, if I add a System.out to the SpringBootServletInitializer#configure(), that does make it to the Console. But if I declare a constructor in my RestController and include a System.out there, that one does not make it to the Console. For good measure, I even tried including a System.err in the constructor and a Logger.getAnonymousLogger.severe in the method; neither of those result in anything.

I should note that this also deploys and runs as expected using an external Tomcat.

I would very much appreciate any input, as it's not likely that I can convince my organization to deploy this to Tomcat nor use the embedded-Tomcat approach (due to politics and an overwhelming existing Glassfish environment).

My test project on Github is here.

like image 623
Bane Avatar asked Apr 04 '14 13:04

Bane


2 Answers

This has been answered here: https://stackoverflow.com/a/29438821/508247

There is a bug in Glassfish 3.1.X. You need to include metadata-complete="true" in your web.xml root element.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" 
     metadata-complete="true"
     xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
</web-app>
like image 132
pmckeown Avatar answered Sep 22 '22 14:09

pmckeown


I had this problem with Payara 5, I understand the problem became from Glassfish.

Versions:

  1. Payara 5.192
  2. Spring Boot 2.1.6

The solution worked for me:

I added this dependency in the pom.xml.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-batch</artifactId>
    <version>2.1.4.RELEASE</version>
</dependency>

My glassfish-web configuration:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC ...>
<glassfish-web-app error-url="">
    <class-loader delegate="true"/>
    <jsp-config>
        <property name="keepgenerated" value="true">
          <description>Keep a copy of the generated servlet class' java code.</description>
        </property>
      </jsp-config>
    <!-- set a friendly context root -->
    <context-root>/micuenta-api</context-root>
    <!-- Change the default character encoding from ISO-8859-1 to UTF-8 -->
    <parameter-encoding default-charset="UTF-8"/>
</glassfish-web-app>
like image 44
Milton BO Avatar answered Sep 21 '22 14:09

Milton BO