JHipster 6.0.1 docker-compose deployment: Java heap space

Alejandro :

I have 2 applications. App 1 is using JHipster 5.8.2 which I deploy to a Digital Ocean's droplet with 2GB RAM and, after pushing my image to gitlab's registry, I run it docker-compose -f app.yml up (which has _JAVA_OPTIONS=-Xmx512m -Xms256m) and everything runs perfect in about 45 seconds.

App 2 was generated with JHipster 6.0.1 (it's actually an upgrade of my App 1). I used a similar droplet from App 1 for my App 2: single core with 2GB RAM but it failed because of Java Heap Space. After this I changed my droplet to 4GB 2 core droplet and changed my app.yml config to this: _JAVA_OPTIONS=-Xmx3072m -Xms2048m but it still fails with the same issue and after 40 minutes.

After this error I tried running the image in my computer with 32GB, after 2 1/2 hours, the same issue arose.

This is how I packed my 6.0.1 app:

  • /mvnw verify -Pprod -DskipTests
  • ./mvnw jib:build -Dimage=registry.gitlab.com/amatos/project

In my droplet:

  • docker-compose -f app.yml up -d

This should work, but it never passes the line Web application fully configured and after several minutes (depending on the amount of RAM), it fails.

Is there an extra step I'm missing?

FINDING:

After doing a lot of testing, I discovered that, by adding a custom DTO I get the Java heap space issue.

Generated DTO:

package com.facturapp.service.dto;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Lob;

/**
 * A DTO for the {@link com.facturapp.domain.Address} entity.
 */
public class AddressDTO implements Serializable {

    private Long id;

    @NotNull
    private String name;

    private String contact;

    private String mobile;

    private String address;

    @Lob
    private String note;

    private Boolean delivery;

    private Boolean invoicing;

    private Boolean active;


    private Long districtId;

    private String districtName;

    private Long partnerId;

    private String partnerName;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContact() {
        return contact;
    }

    public void setContact(String contact) {
        this.contact = contact;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    public Boolean isDelivery() {
        return delivery;
    }

    public void setDelivery(Boolean delivery) {
        this.delivery = delivery;
    }

    public Boolean isInvoicing() {
        return invoicing;
    }

    public void setInvoicing(Boolean invoicing) {
        this.invoicing = invoicing;
    }

    public Boolean isActive() {
        return active;
    }

    public void setActive(Boolean active) {
        this.active = active;
    }

    public Long getDistrictId() {
        return districtId;
    }

    public void setDistrictId(Long districtId) {
        this.districtId = districtId;
    }

    public String getDistrictName() {
        return districtName;
    }

    public void setDistrictName(String districtName) {
        this.districtName = districtName;
    }

    public Long getPartnerId() {
        return partnerId;
    }

    public void setPartnerId(Long partnerId) {
        this.partnerId = partnerId;
    }

    public String getPartnerName() {
        return partnerName;
    }

    public void setPartnerName(String partnerName) {
        this.partnerName = partnerName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        AddressDTO addressDTO = (AddressDTO) o;
        if (addressDTO.getId() == null || getId() == null) {
            return false;
        }
        return Objects.equals(getId(), addressDTO.getId());
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(getId());
    }

    @Override
    public String toString() {
        return "AddressDTO{" +
            "id=" + getId() +
            ", name='" + getName() + "'" +
            ", contact='" + getContact() + "'" +
            ", mobile='" + getMobile() + "'" +
            ", address='" + getAddress() + "'" +
            ", note='" + getNote() + "'" +
            ", delivery='" + isDelivery() + "'" +
            ", invoicing='" + isInvoicing() + "'" +
            ", active='" + isActive() + "'" +
            ", district=" + getDistrictId() +
            ", district='" + getDistrictName() + "'" +
            ", partner=" + getPartnerId() +
            ", partner='" + getPartnerName() + "'" +
            "}";
    }
}

Custom DTO

package com.facturapp.service.dto;

import com.facturapp.domain.District;

/**
 * A DTO for the {@link com.facturapp.domain.Address} entity.
 */
public class AddressFaDTO extends AddressDTO {

    private District district;

    public District getDistrict() {
        return district;
    }

    public void setDistrict(District district) {
        this.district = district;
    }
}

The custom DTO is Address and extends the generated DTO. The generated DTO has a few fields, 2 of them are districtId (Long) and districtName (String), but my custom DTO also has district (District). The class District has a property Province which also has Region, which also has Country. So when I retrieve an Address I also get the district, province, region and country.

My custom Resource calls a custom service that retrieves my custom DTO with the district and all the other classes.

If I use the generated DTO I have no issue, but when I use my custom DTO, the app doesn't run and fails due to the Java Heap space.

Error logs

facturapp_1  | 2019-06-03 06:56:20.395  INFO 1 --- [  restartedMain] com.almasoft.facturapp.FacturApp         : Starting FacturApp on c40efbe18b21 with PID 1 (/app/classes started by root in /)
facturapp_1  | 2019-06-03 06:56:20.407  INFO 1 --- [  restartedMain] com.almasoft.facturapp.FacturApp         : The following profiles are active: prod,swagger
facturapp_1  | 2019-06-03 06:56:45.918  WARN 1 --- [  restartedMain] i.g.j.c.liquibase.AsyncSpringLiquibase   : Warning, Liquibase took more than 5 seconds to start up!
facturapp_1  | 2019-06-03 06:56:57.351  INFO 1 --- [  restartedMain] c.a.facturapp.config.WebConfigurer       : Web application configuration, using profiles: prod
facturapp_1  | 2019-06-03 06:56:57.353  INFO 1 --- [  restartedMain] c.a.facturapp.config.WebConfigurer       : Web application fully configured
facturapp_1  | WARNING: An illegal reflective access operation has occurred
facturapp_1  | WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils (file:/app/libs/spring-core-5.1.6.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
facturapp_1  | WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils
facturapp_1  | WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
facturapp_1  | WARNING: All illegal access operations will be denied in a future release
facturapp_1  | 2019-06-03 07:03:27.207  WARN 1 --- [  restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is com.google.common.util.concurrent.ExecutionError: java.lang.OutOfMemoryError: Java heap space
facturapp_1  | 2019-06-03 07:03:27.606 ERROR 1 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed
facturapp_1  |
facturapp_1  | org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is com.google.common.util.concurrent.ExecutionError: java.lang.OutOfMemoryError: Java heap space
facturapp_1  |  at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:185)
facturapp_1  |  at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:53)
facturapp_1  |  at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:360)
facturapp_1  |  at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:158)
facturapp_1  |  at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:122)
facturapp_1  |  at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:893)
facturapp_1  |  at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:163)
facturapp_1  |  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:552)
facturapp_1  |  at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
facturapp_1  |  at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
facturapp_1  |  at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
facturapp_1  |  at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
facturapp_1  |  at com.facturapp.FacturApp.main(FacturApp.java:63)
facturapp_1  |  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
facturapp_1  |  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
facturapp_1  |  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
facturapp_1  |  at java.base/java.lang.reflect.Method.invoke(Unknown Source)
facturapp_1  |  at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
facturapp_1  | Caused by: com.google.common.util.concurrent.ExecutionError: java.lang.OutOfMemoryError: Java heap space
facturapp_1  |  at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2049)
facturapp_1  |  at com.google.common.cache.LocalCache.get(LocalCache.java:3953)
facturapp_1  |  at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3976)
facturapp_1  |  at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4960)
facturapp_1  |  at springfox.documentation.schema.CachingModelDependencyProvider.dependentModels(CachingModelDependencyProvider.java:58)
facturapp_1  |  at springfox.documentation.schema.DefaultModelProvider.dependencies(DefaultModelProvider.java:128)
facturapp_1  |  at springfox.documentation.schema.CachingModelProvider.dependencies(CachingModelProvider.java:68)
facturapp_1  |  at springfox.documentation.spring.web.scanners.ApiModelReader.populateDependencies(ApiModelReader.java:136)
facturapp_1  |  at springfox.documentation.spring.web.scanners.ApiModelReader.read(ApiModelReader.java:78)
facturapp_1  |  at springfox.documentation.spring.web.scanners.ApiListingScanner.scan(ApiListingScanner.java:133)
facturapp_1  |  at springfox.documentation.spring.web.scanners.ApiDocumentationScanner.scan(ApiDocumentationScanner.java:71)
facturapp_1  |  at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.scanDocumentation(DocumentationPluginsBootstrapper.java:101)
facturapp_1  |  at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start(DocumentationPluginsBootstrapper.java:167)
facturapp_1  |  at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:182)
facturapp_1  |  ... 17 common frames omitted
facturapp_1  | Caused by: java.lang.OutOfMemoryError: Java heap space
facturapp_1  |  at java.base/java.util.Arrays.copyOf(Unknown Source)
facturapp_1  |  at java.base/java.util.ArrayList.grow(Unknown Source)
facturapp_1  |  at java.base/java.util.ArrayList.addAll(Unknown Source)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:181)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromRegularType(DefaultModelDependencyProvider.java:207)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:183)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromRegularType(DefaultModelDependencyProvider.java:207)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:183)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromCollectionElementType(DefaultModelDependencyProvider.java:220)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:181)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromCollectionElementType(DefaultModelDependencyProvider.java:220)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:181)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromCollectionElementType(DefaultModelDependencyProvider.java:220)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:181)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromRegularType(DefaultModelDependencyProvider.java:207)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:183)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1  |  at springfox.documentation.schema.DefaultModelDependencyProvider.dependentModels(DefaultModelDependencyProvider.java:79)
facturapp_1  |  at springfox.documentation.schema.CachingModelDependencyProvider$1.load(CachingModelDependencyProvider.java:50)
facturapp_1  |  at springfox.documentation.schema.CachingModelDependencyProvider$1.load(CachingModelDependencyProvider.java:48)
facturapp_1  |  at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529)
facturapp_1  |  at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278)
facturapp_1  |  at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155)
facturapp_1  |  at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045)
facturapp_1  |  at com.google.common.cache.LocalCache.get(LocalCache.java:3953)
facturapp_1  |  at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3976)

My questions are:

  1. why am I having such issue for just extending a simple DTO?
  2. how can I solve this issue?
Alejandro :

My mistake was using a domain class as a field instead of the DTO class for Address.

The question is still why there is a memory issue when launching the app and not when the method using the faulty class is called.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=83571&siteId=1