5

I have a Spring Boot project that works perfectly when run in IDE. I would like to run this via AWS CodeStar. Unfortunately, the default Spring template created by CodeStar uses Spring MVC.

I cannot just overwrite the default Spring MVC project with my Spring Boot project (it doesn't work). I can copy some of my resources to the MVC project, for example index.html and that works. But then features like Thymeleaf don't work. For this and other reasons, I would like to change the provided Spring MVC into the Spring Boot structure I already have.

I followed the instructions here: https://www.baeldung.com/spring-boot-migration

Unfortunately, this doesn't help. I can create Application Entry Point and add Spring Boot dependencies without the app breaking. But when I remove the default dependencies or the configuration associated with the MVC, the app breaks. When trying to reach the URL, I get a 404 error with description:

The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

Debugging this error message (e.g. https://www.codejava.net/java-ee/servlet/solved-tomcat-error-http-status-404-not-found) didn't help.

The message seems like it's connected to the web resource. I have my web resources in folder resources as well as webapp/resources. And Spring Boot doesn't need any location configuration, right? It uses this location by default.

Can somebody tell me what things to remove and what to add to be able to use my existing Spring Boot project?

EDIT:

This is a link to a default template for AWS CodeStar Spring web application: https://github.com/JanHorcicka/AWS-codestar-template

And this is my Spring Boot project structure:

Structure

Jan Horčička
  • 671
  • 1
  • 11
  • 26
  • can you please help us get minimal starter project generated from aws-codestar in github or somewhere? – silentsudo Jan 06 '21 at 11:50
  • Are you deploying your code to an ec2 or lambda? – David Webster Jan 07 '21 at 23:06
  • EC2. I will post the starter project during the weekend and restart the bounty. – Jan Horčička Jan 08 '21 at 14:17
  • Added a link to the default AWS template. – Jan Horčička Jan 17 '21 at 19:15
  • I am not familiar with codestar, but can you tell me how codestar bootstraps a spring application? Do they deploy it in their own container like tomcat? Do you have control over this? Or can you execute a command to start/stop standalone services? – jms Jan 27 '21 at 10:49
  • @jms You have to provision an EC2 instance (or Elastic Beanstalk). CodeStar packages your code and deploys it there on a Tomcat server. – Jan Horčička Jan 27 '21 at 13:56
  • you should add codestar to the title – Testo Testini Jan 28 '21 at 00:19
  • @JanHorčička I realize that you indicated that previously you tried to use your Spring Boot project with some adaptations without success, but I think it could be actually a possibility, and it will be my advice. Do you mind if I include an answer based in that approach? – jccampanero Jan 28 '21 at 09:36
  • @jccampanero I would be happy if you add any answer that might lead to a solution – Jan Horčička Jan 29 '21 at 00:48
  • Ok. First of all verify that your spring boot application works without the IDE (using the spring boot mvn plugin as used in https://spring.io/guides/gs/spring-boot/). If it does work, setup an separate tomcat locally and follow https://www.baeldung.com/spring-boot-war-tomcat-deploy and deploy the war file in your local instance and check if it's working. Let me know the results. – jms Jan 29 '21 at 03:59

1 Answers1

2

I realize that you indicated that previously you tried to use your Spring Boot project with some modifications without success, but I think it could be actually a possibility to successfully deploy your application on AWS CodeStar, and it will be my advice.

I also realized that in your screenshot you included several of the required artifacts and classes, but please, double check that you followed these steps when you deployed your application to AWS CodeStar.

Let's start with a pristine version of your Spring Boot project running locally, without any modification, and then, perform the following changes.

First, as indicated in the GitHub link you shared, be sure that you include the following files in your project. They are required for the deployment infrastructure of AWS:

  • appspec.yml
  • buildspec.yml
  • template.yml
  • template-configuration.json
  • The whole scripts directory

Please, adapt any necessary configuration to your specific needs, especially, template-configuration.json.

Then, perform the following modifications in your pom.xml. Some of them are required for Spring Boot to work as a traditional deployment and others are required by the deployment in AWS CodeStar.

Be sure that you indicate packaging as war:

<packaging>war</packaging>

To ensure that the embedded servlet container does not interfere with the Tomcat to which the war file is deployed, either mark the Tomcat dependency as being provided as suggested in the above-mentioned documentation:

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

Or exclude the Tomcat dependency in your pom.xml:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
  </exclusions>
</dependency>

If necessary, apply this exclusion using some kind of profile that allows you to boot Spring Boot locally and in an external servlet container at the same time.

Next, parameterize the maven war plugin to conform to the AWS CodeStar deployment needs:

<build>
    <pluginManagement>
        <plugins>
          <!-- ... -->
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-war-plugin</artifactId>
              <version>3.2.2</version>
              <configuration>
                  <warSourceDirectory>src/main/webapp</warSourceDirectory>
                  <warName>ROOT</warName>
                  <failOnMissingWebXml>false</failOnMissingWebXml>
              </configuration>
          </plugin>
          <!-- ... -->
       <plugins>
    </pluginManagement>
</build>

I do not consider it necessary, but just to avoid any kind of problem, adjust the name of your final build:

<finalName>ROOT</finalName>

Lastly, as also indicated in the Spring documentation, be sure that your MyProjectApplication - I assume this class is your main entry point subclass SpringBootServletInitializer and override the configure accordingly, something like:

@SpringBootApplication
public class MyProjectApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MyProjectApplication.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(MyProjectApplication.class, args);
    }

}

Please, feel free to adapt the class to your specific use case.

With this setup, try to deploy your application and see if it works: perhaps you can find some kind of library dependencies problem, but I think for the most part it should work fine.

At a first step, you can try to deploy locally the version of the application you will later deploy to AWS CodeStar following the instructions you provided in your project template, basically, once configured with the necessary changes described in the answer, by running:

mvn clean package

And deploying the generated war on your local tomcat environment. Please, be aware that probably the ROOT application already exists in a standard tomcat installation (you can verify it by inspecting the webapps folder): you can override that war file.

For local testing you can even choose a different application name (configuring build.finalName and the warName in your pom.xml file): the important thing is verify if locally the application runs successfully.

If you prefer to, you can choose to deploy the app directly to AWS CodeStar and inspect the logs later it necessary.

In any case, please, pay attention on two things: on one hand, if you have any absolute path configured in your application, it can be the cause of the 404 issue you mention in the comments. Be aware that your application will be deployed in Tomcat with context root '/'.

On the other hand, review how you configured your database access. Probably you used application.properties and it is fine, but please, be aware that when employing the application the database must be reachable: perhaps Spring is unable to create the necessary datasources, and the persistence manager or related stuff associated with and, as a consequence, the application is not starting. Again, it may be the reason of the 404 error code.

To simplify database connectivity, for testing, at first glance, I recommend you to use simple properties for configuring your datasource, namely the driver class, connection string, username and password. If that setup works properly, you can later enable JNDI or what deemed necessary.

Remember that if you need to change your context name and/or define a datasource pool in Tomcat you can place a context.xml file under a META-INF directory in your web app root path.

This context.xml should look like something similar to:

<?xml version="1.0" encoding="UTF-8"?> 
<Context path="/"> 

  <Resource name="jdbc/myDS" 
    type="javax.sql.DataSource"
    maxActive="100" 
    maxIdle="30" 
    maxWait="10000" 
    url="jdbc:mysql://localhost:3306/myds" 
    driverClassName="com.mysql.jdbc.Driver" 
    username="root" 
    password="secret" 
  /> 

</Context>
jccampanero
  • 50,989
  • 3
  • 20
  • 49
  • Thank you very much for give me the bounty @JanHorčička. Does it mean that the proposed solution worked? – jccampanero Jan 29 '21 at 22:55
  • You deserve it for the effort. This is a high quality answer. Unfortunately, it doesn't help. I started everything from scratch. Created a new project and followed your instructions. I didn't touch the YAML files, because there is no need. I did the exclusion, tried both approaches, just to be sure. Maven WAR plugin and finalName are already provided in the default template in the way you described. I modified the entry point to match the one you provided. I can import all of my classes and dependencies without the app breaking. But once I add my entry point class, I get 404 error. – Jan Horčička Jan 30 '21 at 20:33
  • Thank you very much @JanHorčička. I am very sorry to hear that the application is still not working, I came across several of your questions here and in other forums and it seems like you've been trying to solve the problem for a long time. Please, do you mind if we review the problem in a chat? I will be glad to try to help you in the resolution of the problem if I can. Please, can you give me a time slot where you will be connected to the site? I will try to meet with you. – jccampanero Jan 30 '21 at 22:28
  • I was playing with the local tomcat server. The server works fine with default template provided by CodeStar. It becomes broken when I rename the package. I rename the groupId and the project name using IDE. I didn't forget to rename also the configuration in pom.xml and in @ComponentScan to the new values, but that doesn't help. Funnily enough, even if reset the changes (git reset --hard) to get to the default template, the server doesn't work anymore. That's very odd to me. I would be happy to get some more help on this via chat. In which time zone are you available? I'm in CET. – Jan Horčička Jan 31 '21 at 11:32
  • Hi @JanHorčička. Sorry for the late reply. Well, that is strange. Maybe the first deployment modified some configuration which then broke the server, I honestly don't know. Any way, I think the best approach would be to try and deploy your original Spring Boot project with the necessary modifications, as indicated in the answer. I am in CET as well. Maybe I can get some time this afternoon around 18:00. Or tonight around 23:00. Could you meet at any of these times? If not, please, let me know when you could. – jccampanero Jan 31 '21 at 16:00
  • Link to companion [chat](https://chat.stackoverflow.com/rooms/228083/room-for-jccampanero-and-jan-horcicka). – jccampanero Feb 01 '21 at 09:08