Spring: 404 errors on AWS Elastic Beanstalk (Tomcat)

I had run into a strange issue while trying to deploy a simple “Hello World” application on AWS Elastic Beanstalk. I had gone through all the guides available, set SERVER_PORT to 5000, made sure my main class was extending SpringBootServletInitializer and so on…

My application ran fine locally, I could see “Hello World” in my browser.

While looking at the Beanstalk dashboard, I noticed that it tells me the version of Tomcat and Java: Tomcat 8.5 with Java 8 running on 64bit Amazon Linux/3.2.2

Okay, so Elastic Beanstalk uses these Java versions… so I checked my pom.xml file, and noticed…

...
<java.version>11</java.version>
...

I changed it to 1.8 (Java versioning is weird and inconsistent… 1.8 is Java 8)

I then ran mvn clean package and re-uploaded my war file… and boom, “Hello World” appeared in my browser…

What’s funny is, I didn’t see anything in the Beanstalk logs indicating this was the problem! I just gave it a shot and it fixed the issue.

Are you getting 'undefined' errors in Vue, but devtools says the data is there? You may need conditional rendering.

You may run into a situation where, at some point in your app’s loading or initialization, some nested property on your data object is undefined. Perhaps you open up the devtools extension, and you see that the property is in fact, there.

What gives? You may need conditional rendering. Remember, JavaScript is asynchronous. You may be trying to access that data, before it’s even been loaded.

You can use conditional rendering to make sure that a component, or a block of HTML, is not rendered until a condition is met.

<div id='user-data' v-if="someCondition">
    ...
</div>

Say you have a data object with the property current_user:

data() {
    return {
        current_user: {}
    }
}

Initially, this current_user property is just an empty object. Later on in your app, you use API calls to put data in that property.

async mounted() {
    this.current_user = await this.axios.get("/my-api/user/1.json").data
}

Now you want to display the data:

<div id='user-data' v-if="Object.keys(current_user).length !== 0">
    <div id='user-name'>{{ current_user.name }}</div>
</div>

This block of HTML will be rendered only if there are any properties on this.current_user

There may also be situations where you need to declare a flag, such as:

data() {
    return {
        displayUsersList: false
    }
}

and then flip that switch elsewhere in your code, perhaps when a websocket connection has been made.

channels: {
    ChatRoomChannel: {
        connected() {
            this.displayUsersList = true
        }
    }
}

Perhaps you know that, in your application, you are ready to display the list of users after a websocket connection is made.

In your own app, you’ll need to determine where these conditions need to be flipped.

So, if you’re running into these kinds of issues, where you’re receiving errors saying that properties on your data object are undefined, then you may need conditional rendering. It’s up to you to figure out at what point of execution you’ll need to make the condition true.

You can also read the Vue documentation on Conditional Rendering for more information.