14

I have a very standard Spring Boot application (with a application.properties properties file located in standard /src/main/resources folder) which I'm deploying on AWS Elastic Beanstalk as a "fat JAR". It works quite nicely but there is an issue with image uploading on the server. After some investigation it seems that the NGINX configuration needs to be tweaked (increase client_max_body_size to something so it can accept uploads up to 10MB) and therefore I have added an .ebextensions folder under /src/main/resources with a file with the following content (taken from this answer): -

files:
    "/etc/nginx/conf.d/proxy.conf":
        mode: "000755"
        owner: root
        group: root
        content: |
           client_max_body_size 20M;

However, when I run mvn on my build it doesn't create .ebextensions in the root folder and I'm wondering what is the best solution for this. My pom.xml file is pretty minimal and currently contains the following:

    ...

    <packaging>jar</packaging>

    ....

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

            <dependencies>
                <dependency>
                    <groupId>org.springframework</groupId>
                    <artifactId>springloaded</artifactId>
                    <version>1.2.6.RELEASE</version>
                </dependency>
            </dependencies>

        </plugin>

Thanks in advance!


Update 1

@Lorena when I insert <resources> ... XML into my pom.xml and then start the server it crashes out with the following: -

2017-03-20 21:40:29.504  WARN 10784 --- [           main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'emailApiSpringBootMail': Unsatisfied dependency expressed through field 'javaMailSender'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.mail.javamail.JavaMailSender' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2017-03-20 21:40:29.507  INFO 10784 --- [           main] o.apache.catalina.core.StandardService   : Stopping service Tomcat
2017-03-20 21:40:29.533  WARN 10784 --- [           main] o.s.boot.SpringApplication               : Error handling failed (Error creating bean with name 'delegatingApplicationListener' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.annotation.ProxyCachingConfiguration': Initialization of bean failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' available)
2017-03-20 21:40:29.637 ERROR 10784 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Field javaMailSender in com.myapp.server.api.impl.EmailApiSpringBootMail required a bean of type 'org.springframework.mail.javamail.JavaMailSender' that could not be found.
    - Bean method 'mailSender' not loaded because AnyNestedCondition 0 matched 2 did not; NestedCondition on MailSenderAutoConfiguration.MailSenderCondition.JndiNameProperty @ConditionalOnProperty (spring.mail.jndi-name) did not find property 'jndi-name'; NestedCondition on MailSenderAutoConfiguration.MailSenderCondition.HostProperty @ConditionalOnProperty (spring.mail.host) did not find property 'host'

Removing the XML again fixes the issue so unfortunately this won't work.


Update 2

The issues described in the previous section seemed to be that the new <resources> pointing to the .ebextentions was overridding the <resources> block defined in: -

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

To get everything working I copied it across and appended to the end as follows: -

    <resources>

        <resource>
            <directory>src/main/resources/ebextensions</directory>
            <targetPath>.ebextensions</targetPath>
            <filtering>true</filtering>
        </resource>

        <!-- Followed is copied from `spring-boot-starter-parent.pom` -->

        <resource>
            <directory>${basedir}/src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/application*.yml</include>
                <include>**/application*.properties</include>
            </includes>
        </resource>
        <resource>
            <directory>${basedir}/src/main/resources</directory>
            <excludes>
                <exclude>**/application*.yml</exclude>
                <exclude>**/application*.properties</exclude>
            </excludes>
        </resource>

    </resources>

Thanks everyone for your help!

Community
  • 1
  • 1
bobmarksie
  • 3,282
  • 1
  • 41
  • 54
  • Have you tried telling it in the pom that it should move the folder to the root? [Like this](http://codingexplained.com/coding/java/moving-ebextensions-root-war-file) – imTachu Mar 20 '17 at 13:08
  • 1
    That is for deploying as WAR - I'm deploying as a fat JAR so it's easy to run from command line. – bobmarksie Mar 20 '17 at 14:52
  • Instead of copying the `` section you can use the Build Helper Maven Plugin: https://stackoverflow.com/a/64911750/283136 – timomeinen Nov 19 '20 at 12:35

5 Answers5

7

Here is a pom snippet that'll make it work for a JAR:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>src/main/resources/ebextensions</directory>
            <targetPath>.ebextensions</targetPath>
            <filtering>true</filtering>
        </resource>
        <!-- Followed is copied from `spring-boot-starter-parent.pom` -->
        <resource>
            <directory>${basedir}/src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/application*.yml</include>
                <include>**/application*.properties</include>
            </includes>
        </resource>
        <resource>
            <directory>${basedir}/src/main/resources</directory>
            <excludes>
                <exclude>**/application*.yml</exclude>
                <exclude>**/application*.properties</exclude>
            </excludes>
        </resource>
    </resources>
</build>

It just works in the same way as moving .ebextensions to root in .war file

Actually I uploaded the sample to this repo. Just do a mvn package

bobmarksie
  • 3,282
  • 1
  • 41
  • 54
imTachu
  • 3,759
  • 4
  • 29
  • 56
  • Thanks Lorena for you answer. However, when I added this it the server would not start - question updated. – bobmarksie Mar 20 '17 at 23:00
  • Ok, this looks like it is also filtering your properties. This approach that I show you is a solution that you might need to adjust to your specific situation. (since I don't have the entire context of your application) please, do as mentioned [here](https://github.com/spring-projects/spring-boot/issues/749) and let me know. – imTachu Mar 21 '17 at 05:18
  • As mentioned above - this is very much a standard spring boot application with application.properties in the `/src/main/resources folder` – bobmarksie Mar 23 '17 at 10:05
  • Adding `src/main/resourcestrue` to your solution fixed my issue. – bobmarksie Mar 26 '17 at 00:31
  • Thank you for providing this answer, however I'm wondering why the 2nd and 3rd `resource` children are required for this? It seems to me that omitting those yields the same result. Am I missing something? – oschlueter May 05 '17 at 16:01
  • 1
    For me this works with `spring-boot-starter-parent` at version `1.3.0.RELEASE`, but not with `1.4.6.RELEASE` – johanvs May 20 '17 at 10:06
  • @johanvas - that's interesting - did you get this to work? – bobmarksie Jun 21 '17 at 13:56
  • I tried with Spring Boot 2.0.3 and it seems not to work. Some hint? Could you show how the stucture of the final .jar looks like? Thanks – drenda Nov 12 '18 at 09:26
  • this moves the .ebextension folder in the root of the original jar, not the uber jar created by the plugin, right? – Balázs Németh Oct 03 '19 at 08:25
6

The solution proposed by Lorena Salamanca Spring Boot + Elastic Beanstalk .ebextensions in JAR not works for me... :\

My solution works with Spring 1.5.3.RELEASE

Add .ebextensions in the root of your project and add this snippet at the end in the plugins section:

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.6</version>
            <executions>
                <execution>
                    <id>prepare</id>
                    <phase>package</phase>
                    <configuration>
                        <tasks>
                            <unzip src="${project.build.directory}/${project.build.finalName}.jar" dest="${project.build.directory}/${project.build.finalName}" />
                            <copy todir="${project.build.directory}/${project.build.finalName}/" overwrite="false">
                                <fileset dir="./" includes=".ebextensions/**"/>
                            </copy>
                            <!-- <jar jarfile="${project.build.directory}/${project.build.finalName}.jar" basedir="${project.build.directory}/${project.build.finalName}"/>-->
                            <zip compress="false" destfile="${project.build.directory}/${project.build.finalName}.jar" basedir="${project.build.directory}/${project.build.finalName}"/>
                        </tasks>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

This plugin use ant to unzip the final jar generated by spring boot, copy the .ebextensions in the root and zip (jar) again with the same name. Tested and working in production :)

Javier Arnáiz
  • 710
  • 8
  • 11
  • Have you tested this across older versions too? – bobmarksie Jun 29 '17 at 10:42
  • This worked for me to. The other solution seems a bit less hacky but I cannot get it to work. Thanks for the code @Javier Arnáiz –  Oct 04 '17 at 17:55
  • Spoke too fast. It's giving me [Tomcat-startStop-1] ERROR on.apache.catalina.core.ContainerBase - A child container failed during start :( –  Oct 04 '17 at 18:09
  • I tested this on Spring boot 2.0.0 release version and it is working. Also the solution you mentioned also didn't work for me as it is not coping .elasticbeanstalk folder in root of the jar file. – Jimmy Jul 10 '18 at 07:55
  • This technique is also confirmed to work with Spring Boot 2.1.2, maven 3.6, and the current AWS Elastic Beanstalk (Feb 2019). – Bampfer Feb 21 '19 at 18:56
  • @Bampfer I'm trying this solution but when I do deploy, I've an error from nginx: nginx: [emerg] unknown directive "files:" in /var/elasticbeanstalk/staging/nginx/conf.d/proxy.conf:7. Am I doing something wrong? – drenda Jun 15 '19 at 12:30
  • 1
    @drenda The files directive is supposed to be sent to Beanstalk, telling it to create a file called proxy.conf with the `client_max_body_size` directive in it. From your error it sounds like the "files:" command ended up inside the proxy.conf file instead. My guess would be you put the 'files' command in the folder `.ebextensions/nginx/conf.d` rather than `.ebextensions`. (See top-rated answer to https://stackoverflow.com/questions/18908426/increasing-client-max-body-size-in-nginx-conf-on-aws-elastic-beanstalk - either method can work but don't mix them.) Hope that helps – Bampfer Jun 17 '19 at 03:26
  • @Bampfer Thank you so much! I finally solved this problem that were annoying me from long time! – drenda Jun 17 '19 at 08:19
3

I believe in this case that standalone JAR is used, it's easier to go with Procfile-based configuration and then bundle your JAR and .ebextensions into a zip file.

First create a file, called Procfile in the root of the project with following content:

web: java -jar sample_app-1.0.0.jar

Then create a zip file, containing the JAR and Procfile file and .ebextensions directory:

sample_app.zip
|
|_.ebextensions
|   |_ nginx
|      |_ conf.d
|         |_ proxy.conf
|
|_ sample_app-1.0.0.jar
|_ Procfile
Khashayar
  • 1,321
  • 10
  • 9
0

The error message that you get is for javaMailSender property not found.

The resources path mentioned in your pom.xml overrides the default resources root path.

Hence JavaMailSender is looking for the jndi configuration or the mail properties under this new resources path and its not able to find it.. Hence the error.

spring.mail.jndi-name=mail/testmail

OR

spring.mail.host=testserver.com
spring.mail.port=25
spring.mail.username=test
spring.mail.password=test123
spring.mail.protocol=smtp
spring.mail.defaultEncoding=UTF-8
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.auth.mechanisms=NTLM
spring.mail.properties.mail.smtp.auth.ntlm.domain=DOMAIN
spring.mail.properties.mail.debug=true
Tiny
  • 683
  • 5
  • 18
  • 36
  • I have all these properties in my `application.properties` though and email all works nicely until I added the `` tag. – bobmarksie Mar 21 '17 at 09:41
  • yes. but according to me the javamailsender looks for the same configuration in the new resources path added by you in the pom.xml.. Can you provide the default resources path itself in the pom.xml and check if the issue persists .. – Tiny Mar 21 '17 at 09:47
  • This is very much a standard spring boot application with `application.properties` in the `/src/main/resources` folder – bobmarksie Mar 22 '17 at 11:06
0

Actually it is spring-boot jar related issue. As you are using 1.2.6 version of spring-boot, which has some bugs like javamailsender issue. You need to upgrade your spring boot version more than 1.3.0.release.

In this ticket#3478, the mailsender issue is fixed for spring-boot. So you can upgrade to latest version or others more than 1.3.0 release.

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>1.3.5.RELEASE</version>
</dependency>

Hope this will solve your issue.

SkyWalker
  • 28,384
  • 14
  • 74
  • 132