spring-projects / sts4

The next generation of tooling for Spring Boot, including support for Cloud Foundry manifest files, Concourse CI pipeline definitions, BOSH deployment manifests, and more... - Available for Eclipse, Visual Studio Code, and Theia
https://spring.io/tools
Eclipse Public License 1.0
870 stars 203 forks source link

STS4 fails to launch Spring Boot app with higher number of dependencies #434

Closed SledgeHammer01 closed 4 years ago

SledgeHammer01 commented 4 years ago

In my Maven project, STS4 fails to launch on a Run As Spring Boot app with no warning or error message. Just terminated and/or a crash dump and/or main class missing. I have roughly 30 dependencies in my Pom which really isn't that much.

After a few weeks of fighting this, it seems like its related to classpaths that exceed the class path limit on Windows 10. There is a checkbox in the Run As Configuration to use the temp jar as a workaround for this situation, but there was absolutely no indication of that being the issue.

Oddly, mvnw clean install and running from command line doesn't suffer from the same issue as STS4.

Would definitely save people a ton of time if there was an error message or better handling of this situation.

kdvolder commented 4 years ago

Sounds like this is a duplicate of:

If you don't feel like reading all that, which I can understand. A good summary of the issue and what you can do to try to avoid it is in this post:

https://github.com/spring-projects/sts4/issues/433#issuecomment-606092580

SledgeHammer01 commented 4 years ago

Sounds like this is a duplicate of:

If you don't feel like reading all that, which I can understand. A good summary of the issue and what you can do to try to avoid it is in this post:

#433 (comment)

I have the latest build and boot projects still fail to launch silently / intermittently / crash dump unless you have the temp jar checkbox checked.

kdvolder commented 4 years ago

I have the latest build and boot projects still fail to launch silently / intermittently / crash dump unless you have the temp jar checkbox checked.

Interesting. That means we may need to debug it a bit and try and determine why. However, before we re-open this ticketn and continue with this...

Can we make absolutely sure you have an STs / Eclipse that is based on Eclipse 4.15 or later?

You say:

I have the latest build

Whether you have the latest STS is not the most important question here. This is an Eclipse bug, so we want to know if your STS is based on Eclipse 4.15 (and it is possible to have latest STS installed into older Eclipse!).

I have found in the past people often think that they are on the latest version of Eclipse, when they are not (probably this due to the confusing ways in which Eclipse updates from update sites work).

So can you double check this, so that we are absolutely sure.

Refer to the linked ticket where I posted screenshot of the information to look for.

SledgeHammer01 commented 4 years ago

I have the latest build and boot projects still fail to launch silently / intermittently / crash dump unless you have the temp jar checkbox checked.

Interesting. That means we may need to debug it a bit and try and determine why. However, before we re-open this ticketn and continue with this...

Can we make absolutely sure you have an STs / Eclipse that is based on Eclipse 4.15 or later?

You say:

I have the latest build

Whether you have the latest STS is not the most important question here. This is an Eclipse bug, so we want to know if your STS is based on Eclipse 4.15 (and it is possible to have latest STS installed into older Eclipse!).

I have found in the past people often think that they are on the latest version of Eclipse, when they are not (probably this due to the confusing ways in which Eclipse updates from update sites work).

So can you double check this, so that we are absolutely sure.

Refer to the linked ticket where I posted screenshot of the information to look for.

Yup I have 4.15.

At first, I thought something in my environment got corrupted, so I wiped my machine of every remnant of Java, STS, code, Eclipse, etc. and reinstalled (and re-downloaded) everything. I even wiped my .m2 folder completely and the workspace, etc. Did EVERYTHING 100% fresh, even the code from github was re-imported.

Weird thing when I first ran into the bug was my work machine worked, but my home machine didn't. In hindsight, my code is in my Windows user directory c:\users\Sledge Hammer\workspaces at home, but on my work account, its c:\users\SHammer (LOL), so I get a few extra characters on the work one.

Ran into it when I got up to about 20 dependencies in my POM. More interesting, to maybe point you in a further direction for debugging:

1) when I got up to ~20, the work machine worked (due to the slightly shorter path), but my home machine didn't 2) at ~20, the home machine would work 100% of the time if I did "Run As Java Application" instead of as Spring Boot 3) at ~20 + 1, Run As Java Application stopped working on both machines 4) mvnw clean install / package worked 100% of the time on both machines 5) mvnw run worked 100% of the time on both machines 6) I would either get instant "terminated" (it wouldn't even go through the 45% progress bar hang, it would terminate immediately, a main class missing, or a crash dump w/ a class not found exception

Windows 10 Pro x64, 32GB of RAM, JDK 11.0.6

kdvolder commented 4 years ago

Okay re-opening in this as there seems to be more going on than the already reported/fixed Eclipse bug.

kdvolder commented 4 years ago

Thanks for all that info, I think that gives enough info so we can try play around a bit here and see if one of us can reproduce it.

In the mean time, when your launch failed could you take a look at the details of how the process was launched. What I'm interested is the 'command line' string that you can find in the Debug view as follows:

I'm interesting in seeing that as it may show immediately something wrong with the 'commandline' string which might help us to come up with some theories where/how/why its failing.

martinlippert commented 4 years ago

I tried to reproduce this on a Windows 10 machine running the latest Spring Tools 4 for Eclipse 4.6.1.CI build on Eclipse 4.15, created a project by selecting random dependencies from Initializr and ended up with a project with 344 JAR files on the Maven classpath container. I can start that project up from the boot dashboard (so running as a Spring Boot application) just fine - even though it refuses to completely startup due to some missing bean definitions (caused by my random selection of all those starters). So an interesting question would be what the difference here is...

SledgeHammer01 commented 4 years ago

Thanks for all that info, I think that gives enough info so we can try play around a bit here and see if one of us can reproduce it.

In the mean time, when your launch failed could you take a look at the details of how the process was launched. What I'm interested is the 'command line' string that you can find in the Debug view as follows:

  • Open Debug View(this is the view were you see list of processes and their 'stacks'.
  • Select the crashed / terminated process
  • Right Click and Select 'Properties'.
  • Copy the big string from the 'Command Line' property
  • Paste it here

I'm interesting in seeing that as it may show immediately something wrong with the 'commandline' string which might help us to come up with some theories where/how/why its failing.

Here you go...

"C:\Program Files\Java\jdk-11.0.6\bin\javaw.exe" -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=55342 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=localhost -Dspring.jmx.enabled=true -Dspring.application.admin.enabled=true -noverify -XX:TieredStopAtLevel=1 -Dspring.boot.project.name=xxxx -Dfile.encoding=UTF-8 "@C:\Users\xxxxxx\Workspaces\xxxx\xxxx\.temp-xxxx - xxxxApplication-classpath-arg-1586192260687.txt" org.xxxxxxxxxxxxx.xxxx.xxxxApplication --spring.output.ansi.enabled=always

Anything I blanked out with x's, I left the same number of x's as the real stuff.

Also, here is my POM. I don't think you'll be able to run it due to settings and missing beans, but that'll show you my exact dependencies. If comment out the last netflix one, then it works without the temp jar checkbox.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.xxx</groupId>
    <artifactId>xxxx</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>xxxx</name>
    <description>xxx Microservices</description>
    <packaging>war</packaging>
    <repositories>
        <repository>
            <id>central</id>
            <url>https://repo1.maven.org/maven2/</url>
        </repository>
    </repositories>
    <profiles>
        <profile>
            <id>tomcat</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <properties>
                <spring.profiles.active>tomcat</spring.profiles.active>
            </properties>
        </profile>
        <profile>
            <id>docker</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <properties>
                <spring.profiles.active>docker</spring.profiles.active>
            </properties>
        </profile>
    </profiles>
    <properties>
        <java.version>11</java.version>
        <tomcat.version>9.0.33</tomcat.version>
        <elasticsearch.version>6.8.6</elasticsearch.version>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>28.2-jre</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-jwt</artifactId>
            <version>1.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>8.2.2.jre11</version> <!--$NO-MVN-MAN-VER$-->
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.13.Final</version> <!--$NO-MVN-MAN-VER$-->
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-dbcp</artifactId>
            <version>9.0.33</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>
        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>2.3.7</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.zalando</groupId>
            <artifactId>logbook-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-text</artifactId>
            <version>1.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-neo4j</artifactId>
        </dependency>
        <dependency>
            <groupId>com.graphql-java-kickstart</groupId>
            <artifactId>graphql-spring-boot-starter</artifactId>
            <version>6.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.graphql-java-kickstart</groupId>
            <artifactId>altair-spring-boot-starter</artifactId>
            <version>6.0.1</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
            <version>2.4.4.RELEASE</version> <!--$NO-MVN-MAN-VER$-->
        </dependency>
        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-streams</artifactId>
            <version>2.4.1</version> <!--$NO-MVN-MAN-VER$-->
        </dependency>
        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-clients</artifactId>
            <version>2.4.1</version> <!--$NO-MVN-MAN-VER$-->
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>xxxx</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
SledgeHammer01 commented 4 years ago

Thanks for all that info, I think that gives enough info so we can try play around a bit here and see if one of us can reproduce it.

In the mean time, when your launch failed could you take a look at the details of how the process was launched. What I'm interested is the 'command line' string that you can find in the Debug view as follows:

  • Open Debug View(this is the view were you see list of processes and their 'stacks'.
  • Select the crashed / terminated process
  • Right Click and Select 'Properties'.
  • Copy the big string from the 'Command Line' property
  • Paste it here

I'm interesting in seeing that as it may show immediately something wrong with the 'commandline' string which might help us to come up with some theories where/how/why its failing.

Oh, and here is one of the crash dump logs if that will be useful. This one is throwing the exception on the network interface, but it's pretty random. Sometimes I get a crash dump with a class not found exception, but I don't have that one now.

hs_err_pid11908.log

kdvolder commented 4 years ago

I've re-formmatted the command line string a bit to try and make it easier to see what's there. Just added 'newlines' between the arguments.

"C:\Program Files\Java\jdk-11.0.6\bin\javaw.exe" 
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=55342 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-Djava.rmi.server.hostname=localhost 
-Dspring.jmx.enabled=true 
-Dspring.application.admin.enabled=true 
-noverify 
-XX:TieredStopAtLevel=1 
-Dspring.boot.project.name=xxxx 
-Dfile.encoding=UTF-8 
"@C:\Users\xxxxxx\Workspaces\xxxx\xxxx\.temp-xxxx - xxxxApplication-classpath-arg-1586192260687.txt" 
org.xxxxxxxxxxxxx.xxxx.xxxxApplication 
--spring.output.ansi.enabled=always

So this part of it kind of caught my eye:

"@C:\Users\xxxxxx\Workspaces\xxxx\xxxx\.temp-xxxx - xxxxApplication-classpath-arg-1586192260687.txt" 

I'm suspicious of the spaces in there. Spaces often have special meaning and need special treatment to avoid troubles when cli tools try to parse their commandlines. So they have been the source of many bugs. Implementation that don't make special handling of these spaces to escape them in some way often end up working fine... unless someone has a space in their file name, path name or project name, and then it breaks.

I assume the 'xxx - xxx' in there is some part of your application / project name? If so, could you try renaming it that so its name doesn't have spaces. E.g. if you have something called foo - bar try instead calling it foo-bar or something like that.

Maybe my 'hunch' is wrong, and its not 'another spaces bug' we are dealing with here. But it would be nice to try and confirm it one way or another.

kdvolder commented 4 years ago

Actually... my current theory is that eclipse is adding the " around the @ argument because it contains spaces. But I think the ", while they keep that argument from being 'split up' at the spaces, also probably stops the @ argument from being recognized correctly. It's just a theory right now.

Anyhow... please try get rid of these spaces and see if avoids the problem. If so, then I think we probably have enough information to raise a bug about this with Eclipse. If not... we have to dig deeper and look elsewhere.

kdvolder commented 4 years ago

This one is throwing the exception on the network interface, but it's pretty random. Sometimes I get a crash dump with a class not found exception, but I don't have that one now.

I can't really explain why it would be somewhat random. That doesn't really make sense if the bug is what I think at the moment (spaces in the commandline messing things up). That kind of bug would not produce 'random' fails. So maybe the network error is caused by something else. The 'main class not found' is more like what I'd expect to see when there's some spaces related formatting issues in the commandline.

SledgeHammer01 commented 4 years ago

I've re-formmatted the command line string a bit to try and make it easier to see what's there. Just added 'newlines' between the arguments.

"C:\Program Files\Java\jdk-11.0.6\bin\javaw.exe" 
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=55342 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-Djava.rmi.server.hostname=localhost 
-Dspring.jmx.enabled=true 
-Dspring.application.admin.enabled=true 
-noverify 
-XX:TieredStopAtLevel=1 
-Dspring.boot.project.name=xxxx 
-Dfile.encoding=UTF-8 
"@C:\Users\xxxxxx\Workspaces\xxxx\xxxx\.temp-xxxx - xxxxApplication-classpath-arg-1586192260687.txt" 
org.xxxxxxxxxxxxx.xxxx.xxxxApplication 
--spring.output.ansi.enabled=always

So this part of it kind of caught my eye:

"@C:\Users\xxxxxx\Workspaces\xxxx\xxxx\.temp-xxxx - xxxxApplication-classpath-arg-1586192260687.txt" 

I'm suspicious of the spaces in there. Spaces often have special meaning and need special treatment to avoid troubles when cli tools try to parse their commandlines. So they have been the source of many bugs. Implementation that don't make special handling of these spaces to escape them in some way often end up working fine... unless someone has a space in their file name, path name or project name, and then it breaks.

I assume the 'xxx - xxx' in there is some part of your application / project name? If so, could you try renaming it that so its name doesn't have spaces. E.g. if you have something called foo - bar try instead calling it foo-bar or something like that.

Maybe my 'hunch' is wrong, and its not 'another spaces bug' we are dealing with here. But it would be nice to try and confirm it one way or another.

Uncensored (or censored less lol), it looks something like:

temp-BILL - BillApplication

My Spring Boot project is "BillApplication". The "BILL" portion is coming from spring.application.name. You can't tell from the x's, but its in the -Dspring.boot.project.name=xxxx as well. STS/Eclipse is formatting the command line like that. Nowhere in either name is there a space that I put in there. As a comparison, here is my cmd line WITH the temp jar workaround on the same machine (you'll notice is also has the spaces, it :

"C:\Program Files\Java\jdk-11.0.6\bin\javaw.exe" -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=61360 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=localhost -Dspring.jmx.enabled=true -Dspring.application.admin.enabled=true -noverify -XX:TieredStopAtLevel=1 -Dspring.boot.project.name=xxxx -Dfile.encoding=UTF-8 -classpath "C:\Users\xxxxxx\Workspaces\xxxx\xxxx.temp-xxxx - xxxxApplication-classpathOnly-1586212642985.jar" org.firstamerican.xxxx.xxxxApplication --spring.output.ansi.enabled=always

SledgeHammer01 commented 4 years ago

Actually... my current theory is that eclipse is adding the " around the @ argument because it contains spaces. But I think the ", while they keep that argument from being 'split up' at the spaces, also probably stops the @ argument from being recognized correctly. It's just a theory right now.

Anyhow... please try get rid of these spaces and see if avoids the problem. If so, then I think we probably have enough information to raise a bug about this with Eclipse. If not... we have to dig deeper and look elsewhere.

ACTUALLY, you might be on to something here with the @... it's not the spaces, it's that the @ is supposed to be outside the quotes:

@"C:...." vs "@C:..."

I confirmed this by creating a text file called test.txt. "@test.txt" doesn't work, but @"test.txt" does. Some info on google seems to indicate it's supposed to work both ways. But that might be the bug...

SledgeHammer01 commented 4 years ago

Actually... my current theory is that eclipse is adding the " around the @ argument because it contains spaces. But I think the ", while they keep that argument from being 'split up' at the spaces, also probably stops the @ argument from being recognized correctly. It's just a theory right now.

Anyhow... please try get rid of these spaces and see if avoids the problem. If so, then I think we probably have enough information to raise a bug about this with Eclipse. If not... we have to dig deeper and look elsewhere.

Got some more information for you... did a few more tests.

When I have all the dependencies as shown above and I UNCHECK the temp jar checkbox, it uses the @ inside of the string which is wrong When I have all the dependencies as shown above and I CHECK the temp jar checkbox, it doesn't use the @ sign, it formats the command line without it

Now here's where it gets tricky... the 2 command lines shown above are automatically using the temp file in different ways. When I happen to comment out the netflix eureka dependency, it's within the classpath limit and it formats the command line fully expanded (snipped) -- no quotes or @, i.e.:

C:\Users\xxxxxx\Workspaces\xxxx\xxxx\target\classes;C:\Users\xxxxxx.m2\repository\org\springframework\boot\spring-boot-starter-web\2.2.6.RELEASE\spring-boot-starter-web-2.2.6.RELEASE.jar;C:\Users\xxxxxx.m2\repository\org\springframework\boot\spring-boot-starter\2.2.6.RELEASE\spring-boot-starter-2.2.6.RELEASE.jar;C:\Users\xxxxxx.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.2.6.RELEASE\spring-boot-starter-logging-2.2.6.REL

Sooo... long story short, the netflix eureka dependency pushed me over the class path limit and without the checkbox, the command line is formatted wrong with the @ sign inside the quotes.

I did try to comment out spring.application.name and BILL is not coming from there. Might be coming from artifactid or name in the pom??

SledgeHammer01 commented 4 years ago

Actually... my current theory is that eclipse is adding the " around the @ argument because it contains spaces. But I think the ", while they keep that argument from being 'split up' at the spaces, also probably stops the @ argument from being recognized correctly. It's just a theory right now.

Anyhow... please try get rid of these spaces and see if avoids the problem. If so, then I think we probably have enough information to raise a bug about this with Eclipse. If not... we have to dig deeper and look elsewhere.

Actually #2, the "xxxx - xxxxApplication" is coming from the Run Configuration name. It's formatted like that in there. But I didn't name it like that. STS/Eclipse automatically generates the name with the hyphen and spaces when you do a Run As.

kdvolder commented 4 years ago

Okay I think we are on the right track. Thanks for trying the '@' outside the quotes. I think it fits with my theory about the spaces. And yes, the theory is not that its the spaces themselves that are the problem, but the problem is that the quotes are being (in the wrong place). The quotes are being added because their are spaces.

So I agree with you, I think the 'bug' is the quotes are being added incorrectly. But since quotes are being added (I think) only when there are spaces in the argument... The bug is triggered only with spaces in the mix.

And, yes, looks like these spaces are coming from launch config name, which as you say, is created automatically by STS when you do a 'Run As >> Boot App'.

So, can you try renaming the launch config and removing the spaces from the name? Then see if it helps? If yes, that confirms most of this 'theory', and it provides a potential workaround for you to use until we have a proper fix.

For the fix (assuming we are correct about all the theory :-), I think we should do 2 things:

I can work on both of those sometime later this week.

PS: Might not be obvious how you can 'rename' a launch config... Just open it via menu 'Run >> Run Configurations'. There's a text box with the launch config's name in the dialog, just change that name and save the change.

SledgeHammer01 commented 4 years ago

Okay I think we are on the right track. Thanks for trying the '@' outside the quotes. I think it fits with my theory about the spaces. And yes, the theory is not that its the spaces themselves that are the problem, but the problem is that the quotes are being (in the wrong place). The quotes are being added because their are spaces.

So I agree with you, I think the 'bug' is the quotes are being added incorrectly. But since quotes are being added (I think) only when there are spaces in the argument... The bug is triggered only with spaces in the mix.

And, yes, looks like these spaces are coming from launch config name, which as you say, is created automatically by STS when you do a 'Run As >> Boot App'.

So, can you try renaming the launch config and removing the spaces from the name? Then see if it helps? If yes, that confirms most of this 'theory', and it provides a potential workaround for you to use until we have a proper fix.

For the fix (assuming we are correct about all the theory :-), I think we should do 2 things:

  • We (STS) should revisit how it names 'Run As >> Boot App' launches and try to avoid putting spaces into their names. (Doesn't fix this bug, but would avoid it, or similar 'space-triggered' bugs)
  • We raise a bug against Eclipse with an example on how to reproduce this problem in a plain Eclipse with 'Run As >> Java'.

I can work on both of those sometime later this week.

PS: Might not be obvious how you can 'rename' a launch config... Just open it via menu 'Run >> Run Configurations'. There's a text box with the launch config's name in the dialog, just change that name and save the change.

Well that's disappointing. Our theory is wrong lol. So I do think the @ is being quoted wrong, that's one potential issue, although like I said, some info on the web seems to say it will work either way. But this is how the cmd line comes back without the spaces (no quotes) in the run config name and it still fails to find the main class.

Oddly, I'm not sure where its getting the JDK path from. I specifically set JAVA_HOME to the short path c:\progra~1... to avoid spaces in the name issues there.

"C:\Program Files\Java\jdk-11.0.6\bin\javaw.exe" -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=49526 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=localhost -Dspring.jmx.enabled=true -Dspring.application.admin.enabled=true -noverify -XX:TieredStopAtLevel=1 -Dspring.boot.project.name=xxxx -Dfile.encoding=UTF-8 @C:\Users\xxxxxx\Workspaces\xxxx\xxxx.temp-xxxx-xxxxApplication-classpath-arg-1586290970918.txt org.xxxxxxxxxxxxx.xxxx.xxxxApplication --spring.output.ansi.enabled=always

kdvolder commented 4 years ago

Oddly, I'm not sure where its getting the JDK path from. I specifically set JAVA_HOME to the short path c:\progra~1... to avoid spaces in the name issues there.

Eclipse doesn't really care about 'JAVA_HOME' environment variable. THe JRE used to launch an app is controlled by a combination of configuration options in your launch config, your project, and workspace settings. Whatever you do inside of the launch config or project can affect exactly which JRE is used. But any JRE used there comes from the list of known JREs that you find configured under "Window >> Preferences >> Java >> Installed JREs".

Spaces in that part of the command aren't really too suspicuous though. If those spaces where the cause we'd probably have 100s of bug reports by now as a lot of folks on Windows would be hitting it.

kdvolder commented 4 years ago

Well that's disappointing...

Indeed, that's a bit back to square one :-(

I'll try find some time myself to play around in Windows VM a bit. But I'm a bit at a loss what the problem could really be (if its not the quotes in front of the '@' symbol).

What about the contents of the '@' file itself. Anything strange in there? Does the file exist? Do the files it points to exist... etc.

SledgeHammer01 commented 4 years ago

Well that's disappointing...

Indeed, that's a bit back to square one :-(

I'll try find some time myself to play around in Windows VM a bit. But I'm a bit at a loss what the problem could really be (if its not the quotes in front of the '@' symbol).

What about the contents of the '@' file itself. Anything strange in there? Does the file exist? Do the files it points to exist... etc.

It was a little tricky to get that file. It only exists for a second or two before Eclipse deletes it since its just a temp file.

The file is 32,054 bytes, so I suspect its running into the classpath length limitation. No spaces in it other then the one between -classpath and the classpath itself. Just for fun, I tried to run the command line from the command prompt and it did nothing. Just exited out. Tried with both the @ in the quotes and outside.

martinlippert commented 4 years ago

I have to correct myself, the testing that I did previously on my Windows machine was wrong (used JDK8). Re-running those tests using AdoptOpenJDK-11 reproduces the described issues in a reliable way.

There are a few bugs at Eclipse where people has worked in this area, so I would highly recommend to file a bug at Eclipse. Since thee is a workaround available (the checkbox to use a temp jar), I wonder what the underlying issues with launching the app without that checkout really are, but I doubt that we can solve this here. Has to be discussed with the teams working on the launching support within JDT, I think.

martinlippert commented 4 years ago

Hmmm... This is strange... I tried the same project on my Windows machine with a plain Eclipse 2020-03 Java installation and it works just fine, so it looks like I was wrong again and it is related to the launch config support in STS somehow. This needs further investigation... Sigh...

martinlippert commented 4 years ago

Okay, here are a few more details from my analysis (all with Spring Tools 4.6.0 and AdoptOpenJDK-11 on Windows 10):

The reason for the "Run as Spring Boot Application" launch config not working is the extra param that is adds to the launch config as a regular program param:

--spring.output.ansi.enabled=always

As soon as you add this param to the program args section (also in the regular Java launch config), the app doesn't start anymore. To be more precise, the app fails to launch as soon as you put any random program arg that starts with a -- in the program args. I don't know why, but that is causing this.

You can workaround this via by disabling the ANSI Console Output option in the launch config.

As a side effect, you won't get colored ANSI console output anymore. If you want to keep having that colored console output, you could either add:

-Dspring.output.ansi.enabled=always

to the VM args of the launch config or add it to the Preferences -> Spring -> Boot section for the fast startup params. That will be put on the launch config automatically for you when you have the fast startup option enabled in the launch config (which is enabled by default). It is not really an option to improve the startup speed of the app, but it could work as a workaround.

You would need to keep in mind that the default setting of the ANSI Console Output in the launch config is smart enough to check whether you have the ANSI Coloring plugin for Eclipse installed or not, but I think we can ignore that for a moment here.

@SledgeHammer01 Can you double check whether this workaround fixes the issue on your side, too? That would be awesome.

kdvolder commented 4 years ago

@martinlippert The difference with the extra argument may be not because the argument itself, but just the fact that adding the argument makes the command string longer and Eclipse starts using the '@' argument when the string reaches a certain length. So a possibility is that that argument will push you over the limit.

If it's really true that it is the argument: --spring.output.ansi.enabled=always itself that is the problem rather than just the extra length of it. Then you can get the same effect of this argument via a system property set by VM argument: -Dspring.output.ansi.enabled=always (so this argument goes before the main class name rather than after it).

kdvolder commented 4 years ago

Re-running those tests using AdoptOpenJDK-11 reproduces the described issues in a reliable way.

That's good news ... I'll will do some testing myself today and if I can reproduce it I may be able to debug it as well.

SledgeHammer01 commented 4 years ago

@martinlippert @kdvolder My work machine is first initial+last name, no spaces. My home is first name+space+last name, so my home has an extra 3 chars on every jar in the classpath, so it would go over the limit much sooner. The code and .m2 directories are within the user directory which is c:\users\xxx. The home machine has a space in the username, so that might be an additional issue, but it works up until a certain number of dependencies, so who knows.

With the pom I posted, Run As Java Application no longer works on either machine without the temp jar checkbox. I was using that workaround on my home machine at first, since if I take off one dependency it'll work again.

I guess, really, the issue is 1) why it doesn't work without the temp jar checkbox (which I guess is the whole point of the checkbox) 2) why it doesn't warn you about having to use the checkbox or apply it automatically since it seems to automatically change the way it works without the checkbox depending on the classpath length.

kdvolder commented 4 years ago

2) why it doesn't warn you about having to use the checkbox or apply it automatically

I think that's just because this is a bug. It is intended to work whether or not you check that box. That it doesn't work is an 'accident' its not by design. So naturally there is no warning for it either (that would imply the implentors who made the bug knew about it, in which case they probaby would have rather fixed it instead).

That still doesn't explain exactly why it doesn't work of course.

kdvolder commented 4 years ago

I tried something on Windows and its getting unfortunately more confusing / mysterious.

It launched fine. The 'commandline' string from the debug view seems to have all the things going on that we previously theorized might be what's breaking it.

C:\openjdk\jdk-11.0.6+10\bin\javaw.exe 
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=50250 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-Djava.rmi.server.hostname=localhost 
-Dspring.jmx.enabled=true 
-Dspring.application.admin.enabled=true 
-noverify 
-XX:TieredStopAtLevel=1 
-Dspring.boot.project.name=demo 
-Dfile.encoding=UTF-8 
"@C:\workspace\demo\.temp-demo - DemoApplication-classpath-arg-1586460261078.txt"
com.example.demo.DemoApplication 
--spring.output.ansi.enabled=always

It has

And yet it launches just fine.

kdvolder commented 4 years ago

I think the length of the commandline string is somehow responsible for.

I made my commandline longer by adding a bunch of arbitrary 'property values assignment' in the launch conf editor.

So now my commandline ends up being this:

C:\openjdk\jdk-11.0.6+10\bin\javaw.exe 
-agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:50315 
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=50314 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-Djava.rmi.server.hostname=localhost 
-Dspring.jmx.enabled=true 
-Dspring.application.admin.enabled=true 
-noverify 
-XX:TieredStopAtLevel=1 
-Dspring.boot.project.name=demo 
-javaagent:C:\sts-4.6.1.CI-B2226\configuration\org.eclipse.osgi\245\0\.cp\lib\javaagent-shaded.jar 
-Dfile.encoding=UTF-8 "@C:\workspace\demo\.temp-demo - DemoApplication-classpath-arg-1586463000477.txt" 
com.example.demo.DemoApplication 
--spring.output.ansi.enabled=always 
--foobaasdasdasd11=sometjhing 
--foobaasdasdasd10=sometjhing 
--foobaasdasdasd29=sometjhing 
--foobaasdasdasd28=sometjhing 
--foobaasdasdasd27=sometjhing 
--foobaasdasdasd26=sometjhing 
--foobaasdasdasd25=sometjhing 
--foobaasdasdasd24=sometjhing 
--foobaasdasdasd23=sometjhing 
--foobaasdasdasd22=sometjhing 
--foobaasdasdasd9=sometjhing 
--foobaasdasdasd21=sometjhing 
--foobaasdasdasd8=sometjhing 
--foobaasdasdasd20=sometjhing 
--foobaasdasdasd7=sometjhing 
--foobaasdasdasd6=sometjhing 
--foobaasdasdasd5=sometjhing 
--foobaasdasdasd4=sometjhing 
--foobaasdasdasd3=sometjhing 
--foobaasdasdasd2=sometjhing 
--foobaasdasdasd=sometjhing 
--foobaasdasdasd34=sometjhing 
--foobaasdasdasd33=sometjhing 
--foobaasdasdasd32=sometjhing 
--foobaasdasdasd31=sometjhing 
--foobaasdasdasd30=sometjhing 
--foobaasdasdasd19=sometjhing 
--foobaasdasdasd18=sometjhing 
--foobaasdasdasd17=sometjhing 
--foobaasdasdasd16=sometjhing 
--foobaasdasdasd15=sometjhing 
--foobaasdasdasd14=sometjhing 
--foobaasdasdasd13=sometjhing 
--foobaasdasdasd12=sometjhing

And in this case I'm getting a JVM crash with this message:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (c:/cygwin64/tmp/openjdk-jdk11u-windows-x86-32-hotspot/workspace/build/src/src/hotspot/share/runtime/signature.cpp:53), pid=9476, tid=3428
#  fatal error: expecting (
#
# JRE version: OpenJDK Runtime Environment (11.0.6+10) (build 11.0.6+10)
# Java VM: OpenJDK Client VM (11.0.6+10, mixed mode, serial gc, windows-x86)
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\workspace\demo\hs_err_pid9476.log
#
# If you would like to submit a bug report, please visit:
#   https://github.com/AdoptOpenJDK/openjdk-support/issues
#
kdvolder commented 4 years ago

Theory, perhaps this isn't actually a bug in Eclipse. Maybe this is hitting some limits in the commandline processing code of the JVM itself. I.e. your typical C / C++ buffer overflow when you present it with too much data.

At first I though maybe it's a limit on Java String / array size somehow being exceeded. But that seems unlikely given that array size limits (in Java at least) are upto maxint number of characters.

I don't know much about how the Java cli is implemented but maybe parts of it are implemented in C++, in which case buffer overflow is a possibility. And that could cause all sorts of strange effects, including random looking JVM crashes due to memory corruption.

kdvolder commented 4 years ago

At least in Java 8 cli was implemented in c. http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/bin/java.c

Haven't found the source for jdk11 java command yet. But I'd assume it's probably also c code.

kdvolder commented 4 years ago

I'm getting somewhat random behavior here. So now I can't really say for sure if changing the length of the argument list was the problem cause/trigger.

Even with all the extra arguments it doesn't always fail to launch. I just ran the same thing over and over and this was the result:

I never once got the class not found message.

I then also tried again with no extra property arguments, and repeated this experiment:

The buffer overflow in the JVM itself is still the best explanation I can think of that fits with this behavior.

THe tricky thing is that it sometimes works (which I think fits with a buffer overflow).

Because it sometimes works, I think a lot of our previous 'theories' were drawing conclusions too soon from a single succesful run and then trying to change something, and then blaming this change for something that may just have been just as well attributable to chance.

In any case I think the theories about '@' argument quoting, spaces and '--' arguments being responsible seems false. Since I've seen it work just fine with all of those things in the mix.

kdvolder commented 4 years ago

For 'completeness' I also launched a dozen or so times with the 'temporary jar' checkbox enabled. It ran fine every single time.

kdvolder commented 4 years ago

I think I have pretty conclusive proof that this isn't an STS or even an Eclipse bug.

I get same behavior launching on commandline. I grabbed the classpath file that eclipse created. Saved it. Then I made a small bash script containing this:

#!/bin/bash
/c/openjdk/jdk-11.0.6+10/bin/javaw.exe \
    -Dcom.sun.management.jmxremote \
    -Dcom.sun.management.jmxremote.port=51848 \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Djava.rmi.server.hostname=localhost \
    -Dspring.jmx.enabled=true \
    -Dspring.application.admin.enabled=true \
    -noverify \
    -XX:TieredStopAtLevel=1 \
    -Dspring.boot.project.name=demo \
    -Dfile.encoding=UTF-8 \
    "@C:\workspace\demo\classpath.txt" \
    com.example.demo.DemoApplication \
    --spring.output.ansi.enabled=always

I then ran this bash script a few times from git bash cli.

I get the same 'randomly crashes or runs fine' behavior as launching from Eclipse.

Since neither Eclipse nor STS is involved in this scenario, it seems the problem is indeed coming from the JVM itself.

kdvolder commented 4 years ago

To resolve this issue, I think we can/should:

kdvolder commented 4 years ago

Sorry didn't mean to close it just clicked wrong button.

SledgeHammer01 commented 4 years ago

I'm getting somewhat random behavior here. So now I can't really say for sure if changing the length of the argument list was the problem cause/trigger.

Even with all the extra arguments it doesn't always fail to launch. I just ran the same thing over and over and this was the result:

  • starts fine: 6 times
  • jvm exits with no output printed in console: 4 times
  • jvm exits with JVM crash message in console: 3 times

I never once got the class not found message.

I then also tried again with no extra property arguments, and repeated this experiment:

  • starts fine: 5 times
  • jvm exits with JVM crash message in console: 6 times

The buffer overflow in the JVM itself is still the best explanation I can think of that fits with this behavior.

THe tricky thing is that it sometimes works (which I think fits with a buffer overflow).

Because it sometimes works, I think a lot of our previous 'theories' were drawing conclusions too soon from a single succesful run and then trying to change something, and then blaming this change for something that may just have been just as well attributable to chance.

In any case I think the theories about '@' argument quoting, spaces and '--' arguments being responsible seems false. Since I've seen it work just fine with all of those things in the mix.

When I first went down this very deep rabbit hole lol... let's call the max working number of dependencies X. When I went X+1, I would see "random looking crashes", so that fits in with your buffer overflow theory. Out of 6 times, it'd work 1. The other 5 were a mixture of crash dump for class not found, crash dump for the network interface that I attached or main class missing. At X+1, the Run As Java App would work, but the Run As Boot wouldn't (at home). So maybe it is a buffer overflow...

SledgeHammer01 commented 4 years ago

To resolve this issue, I think we can/should:

  • enable the 'use temporary jar' option automatically for STS boot app launches
  • raise a bug with Eclipse reporting the issue so they may consider also doing this for 'Run As >> Java' launches and/or other launches from Eclipse that may be affected.
  • raise a JDK bug to report the problem

I dunno about you, but from now on, when I build a spring boot app, I'm checking that box from day 1 lol. I have a console app (this one is Gradle) and I think I'm up to maybe 10 dependencies, and I started getting the main class not found. Clicked the temp jar and it fixed it. I think this is due to the netflix jars having really long names.

kdvolder commented 4 years ago

I've submitted JDK bug. I'd provide a link, but their process has a 'internal review' step first so there's nothing to link just yet.

martinlippert commented 4 years ago

With all those findings, I think we should report this to Eclipse, too, but we should not implement anything special in STS. But discussing the default setting for the temp jar checkbox with the team at Eclipse would be good.

Closing this item here. Kris, please paste the bugs at JDK and Eclipse once they are available.

kdvolder commented 4 years ago

Here's the Eclipse bug I just filed: https://bugs.eclipse.org/bugs/show_bug.cgi?id=562074

kdvolder commented 4 years ago

Here's the JDK bug that just became visible:

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8244611