jetty / jetty.project

Eclipse Jetty® - Web Container & Clients - supports HTTP/2, HTTP/1.1, HTTP/1.0, websocket, servlets, and more
https://eclipse.dev/jetty
Other
3.83k stars 1.91k forks source link

Embedded Jetty 10 and up - WebAppContext cannot parse jar:file ExternalForm resources from JAR #8549

Closed StefanViljoen closed 2 years ago

StefanViljoen commented 2 years ago

Jetty Version: Jetty 10.0.0 up to Jetty 11.0.11 inclusive

Java Vendor: java version "17.0.4.1" 2022-08-18 LTS Java(TM) SE Runtime Environment (build 17.0.4.1+1-LTS-2) Java HotSpot(TM) 64-Bit Server VM (build 17.0.4.1+1-LTS-2, mixed mode, sharing

Operating system: Linux, Ubuntu 20.04 LTS

Description:

In a .jar with an embedded Jetty from version 10.0.0 and up, the WebAppContext class cannot parse resources inside the same JAR Jetty is embedded in specified in the format "jar:file:..."

All HTTP requests received by the server for any web content inside the JAR in which Jetty is embedded fail with 404 not found.

Regressing Jetty back to, for example, 9.4.48.v20220622, and jar:file references are again parsed by the WebAppContext class in the Jetty instance embedded in the same JAR file.

How to reproduce:

In the JAR from which the embedded Jetty instance runs, there is a "static" folder in the root of the jar.

The "static" folder contains an index.html to render.

The JAR must be run in a detached JRE - not inside an IDE because it functions correctly as long as run inside the IDE (Netbeans 14 in my case) as the WebAppContext contextPath then becomes file:///... instead of jar:file:...

Code - WebHost.java:

server = new Server(AppSettings.getJettyServerPort());

String webDir = this.getClass().getClassLoader().getResource("static").toExternalForm();
WebAppContext waContext = new WebAppContext(webDir, "/"); 

waContext.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");

server.setHandler(waContext);

server.setStopAtShutdown(true);
server.setStopTimeout(0x2710L);

server.start();

With

"webDir" = jar:file:/usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static

for 127.0.0.1:8086/index.html

Jetty 10.0.0 and up returns

<html><body>
<!--StartFragment--><h2>HTTP ERROR 404 Not Found</h2>
URI: | /index.jsp
-- | --
404
Not Found
org.eclipse.jetty.servlet.ServletHandler$Default404Servlet-5dc3fcb7

<!--EndFragment-->
</body>
</html>
<br>

Regress to latest Jetty 9, above works correctly, and

jar:file:/usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static

can be resolved by the WebAppContext class, in a detached JRE, separate from the IDE, under Linux.

joakime commented 2 years ago

Some things that stand out ...

Keep in mind that Jetty 10+ jar files have valid module-info.class files. This means the JVM access rules for what's in the JAR files are different than Jetty 9 and older. This is important to recognize.

Don't use a jar-with-dependencies with a WebApp / WAR based context. WebApp rules on packaging are super strict and about how components are found/discovered.

Don't use META-INF/MANIFEST.MF based jar dependencies, there are too many bugs in Java 9+ with jars that have module-info.class files (or that use MultiRelease Jar files).

Either use a ServletContextHandler (instead of a WebAppContext) if you insist on using a jar-with-dependencies, or if just must use a WebAppContext then use an executable "live" war file (to maintain that uber behavior that some jar-with-dependencies configurations have).

  1. Uber-jar with ServletContextHandler example -> https://github.com/jetty-project/embedded-jetty-uber-jar
  2. Self executing "live" War File example -> https://github.com/jetty-project/embedded-jetty-live-war

The URI reference you have has an invalid syntax.

jar:file:/usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static

That's a badly formatted URI, like what is seen from the buggy java.io.File class. The correct syntax should be ...

jar:file:///usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static

Your technique for obtaining the webDir is unreliable.

String webDir = this.getClass().getClassLoader().getResource("static").toExternalForm();

Requesting a directory via .getResource(String) is unreliable across JVMs. It would be best to always request a file, and then resolve to the directory. Eg: if you have a /static/index.html, then use .getResource("static/index.html") and then clean up the resulting URL (tip: use URI.resolve("./"))

Break up your webDir setup. It will be different in the IDE vs standalone, as you are not bundled into a JAR in the IDE.

String webDir = this.getClass().getClassLoader().getResource("static").toExternalForm();
WebAppContext waContext = new WebAppContext(webDir, "/"); 

For starters, when in your IDE, you are not executing in a JAR, esp a jar-with-dependencies, so that means you don't have jar:file:// reference ever, and your classpath will need to be built from where the IDE is storing the components you need. So that means using WebAppContext.setBaseResource() and WebAppContext.setExtraClassPath() when in your IDE. For production, you use WebAppContext.setWar() only.

to something like ...

        WebAppContext context = new WebAppContext();
        context.setContextPath("/");

        switch (getOperationalMode())
        {
            case PROD:
                // Configure as WAR
                context.setWar(basePath.toString());
                break;
            case DEV:
                // Configuring from Development Base
                context.setBaseResource(new PathResource(basePath.resolve("src/main/webapp")));
                // Add webapp compiled classes & resources (copied into place from src/main/resources)
                Path classesPath = basePath.resolve("target/thewebapp/WEB-INF/classes");
                context.setExtraClasspath(classesPath.toAbsolutePath().toString());
                break;
            default:
                throw new FileNotFoundException("Unable to configure WebAppContext base resource undefined");
        }

See: https://github.com/jetty-project/embedded-jetty-live-war/blob/jetty-10.0.x/theserver/src/main/java/jetty/livewar/ServerMain.java

Depending on the style of "jar-with-dependencies" you are using, it could easily be incompatible with org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern.

If you are using the META-INF/MANIFEST.MF based dependencies, then the pattern is very likely not going to work, as Jetty is unable to see into the system classloader entries reliably on Java 9+ based JVMs (it can work on some systems, not on others). If you are using any kind of uber jar with your jar-with-dependencies configuration, then you have no container JARs to configure.

You have no webdefault.xml being used.

org.eclipse.jetty.servlet.ServletHandler$Default404Servlet-5dc3fcb7

That says you are using the bare-bones WebAppContext, it doesn't even have a typical DefaultServlet, and has been setup for Default404Servlet which will always return a 404. This is problem with your jar-with-dependencies again. It's messed up your access within the jetty-http jars.

StefanViljoen commented 2 years ago

Thanks joakime! What would you suggest? I cannot easily convert the format of this project to a .war (for example) as it is a -massive- project of which Jetty is but a tiny, embedded part.

joakime commented 2 years ago

First off, which style of "jar-with-dependencies" are you using? (I've seen about 6 different types in the wild now).

If you rely on dependencies to be linked in META-INF/MANIFEST.MF then you have a lot of work ahead of you.
As once you cross the JVM barrier from Java 8 (where this was common and pretty reliable) to Java 9+ (where module-info.class is important to the JVM to specify cross dependency interaction), you now have different behavior you are probably not taking into account.

If you can guarantee that NONE of your dependencies have a module-info.class (or META-INF/versions/* tree) then continue to use the META-INF/MANIFEST.MF based dependencies. (but this is highly unlikely, as even logging libraries like log4j have these now)

I suspect you'll likely have to use a different approach in starting/bootstrapping your project for the new reality that is Java 9+.

StefanViljoen commented 2 years ago

How can I determine what type I'm using?

It is a Maven based project and Maven (as far as I can tell) handles all the implementation details of the "jar-with-dependencies".

The problem is this project was inherited from someone senior who is no longer available to advise.

How can I tell if I rely on meta-inf/MANIFEST.MF ? I have these files in several folders in the project "jar-with-dependencies" if I examine it in an unzipped state.

It sounds like I'll need to scrap the project, which is not really possible as about 6 years of full-time development by an entire team have been sunk into it - Jetty is how the project communicates over HTTP with other software which requests services from this project. I'm forced to update it as we're under security review and the existing Java 8 / Jetty 9 solution is horribly insecure - and as is published here, Jetty 9 is no longer supported anymore anyway.

Jetty is the frontend to about 98 APIs running in this system, this seems to imply I'll need to completely rewrite every single one of those, plus the entire HTML galaxy of the project (about 100 distinct JSP pages / beans, all reliant on Jetty to parse and serve the JSP logic and content.)

Not good.

Thanks anyway...

Regards

Stefan

StefanViljoen commented 2 years ago

Hi Joakime

Discussed this a bit with some guys here and we simply cannot make the time investment to effectively redevelop a project with six man years invested in it just so we can read resources for Jetty from a JAR, and host in a detached JRE on a Linux machine.

Because that is all that is broken - we cannot get resources out of a .JAR under JDK 17 and Jetty 11.0.11. Otherwise, it all still works perfectly in JDK 17 with Jetty 11.0.11.

We have Windows machines at all the sites this needs to run at, we think we'll simply install Netbeans 14 at each site, deploy the Jetty 11.0.11 source on that Netbeans 14 IDE instance, and install JDK 17 JRE at each site in Windows, and literally run the system off the Windows machine's live running Netbeans 14 under JDK 17 and Jetty 11.0.11... problem kind of solved.

Thanks again for your time and answers. :)

joakime commented 2 years ago

Discussed this a bit with some guys here and we simply cannot make the time investment to effectively redevelop a project with six man years invested in it just so we can read resources for Jetty from a JAR, and host in a detached JRE on a Linux machine.

The change required is how you start your project, the rest of the code wouldn't need to change. In other words, you have to start the JVM correctly depending on how you intend to use the JVM (eg: classpath mode vs module mode). Maven, for example, will execute your projects with module mode if you have module-info.class files present, classpath if you don't.

This is not unique to yourself or your project, every project that has moved beyond Java 8 has had to deal with this at one point or another.

How are you doing "jar-with-dependencies"? (you still haven't answered this) What maven plugin (and configuration) are you using to produce that end result?

You can check your produced JAR files, if they contain a META-INF/MANIFEST.MF with a Class-Path entry (to jar files) then you have the type of configuration that worked fine in Java 8, but has to be updated for Java 9+.

Because that is all that is broken - we cannot get resources out of a .JAR under JDK 17 and Jetty 11.0.11.

That absolutely works, the two projects I listed above do exactly that.

Accessing Resource from a JAR can be done in a dozen different ways, make sure you use the technique that fits your use case. Eg: ClassLoader.getResource(String) / Class.getResource(String) / zipfs / URLConnection / ServletContext.getResource() / etc ...

Regarding some of the advice in the prior comment from me, here's another example of WebAppContext and resources in a JAR.

And if you notice, this example does not rely on webdefault.xml (like your system), but instead adds the DefaultServlet manually in the embedded mode. You can even do multiple DefaultServlet instances serving content from different locations.

You could even use a Jetty ResourceCollection to serve multiple source directories on the same url-pattern, have at it.

An alternative is to simply not fight jar-with-dependencies behavior changes and just use your war file normally. Using a normal jetty-home/jetty-base split instead? (doesn't help with your IDE concern, but it would fix your jar-with-dependencies concern)

joakime commented 2 years ago

Jetty is the frontend to about 98 APIs running in this system, this seems to imply I'll need to completely rewrite every single one of those, plus the entire HTML galaxy of the project (about 100 distinct JSP pages / beans, all reliant on Jetty to parse and serve the JSP logic and content.)

The only rewrite would be for the Jetty 11 and its use of Jakarta EE 9 and the namespace change.

If you go to Jetty 12, then you'll have a different rewrite to not use deprecated methods in the servlet spec (they have been deprecated for a while, and are now removed in Jakarta EE 10, which will ship with Jetty 12)

Note, that if you move to Jetty 11, these JSP files will need to be touched / updated to satisfy the Jakarta "big bang" to use the new namespaces. (and to use the new XML schema locations for your TLDs)

The old javax.* namespace for EE libs is dead, now they are on jakarta.*. If you use Spring, know that Spring 6 will be moving whole-hog to this new namespace as well.

sbordet commented 2 years ago

@joakime I think what reported by @StefanViljoen is a legit regression.

Should not matter whether we have module-info.java files in Jetty 10+, and neither whether the JVM starts with JPMS.

@lorban can you please write a test and verify whether we really can't serve jar:file: resources? I'm surprised we don't have a test already.

StefanViljoen commented 2 years ago

The change required is how you start your project, the rest of the code wouldn't need to change. In other words, you have to start the JVM correctly depending on how you intend to use the JVM (eg: classpath mode vs module mode). Maven, for example, will execute your projects with module mode if you have module-info.class files present, classpath if you don't.

How would I do that? E. g. start the JVM in the "correct way" and switch between these two modes? I've not seen any references anywhere about the above, all this is completely new to me... thanks for assisting.

This is not unique to yourself or your project, every project that has moved beyond Java 8 has had to deal with this at one point or another.

That makes sense, but it still calls into question the entire Jetty / Java infrastructure we've spent... well, not millions, but close to it, to invest in and build up over about seven years of work. Time to look at something else maybe... we cannot afford to have to do this every six months or so, as looks likely looking at the release cycles. But that is beside the point. Maybe Spring with Tomcat? Don't know.

How are you doing "jar-with-dependencies"? (you still haven't answered this) What maven plugin (and configuration) are you using to produce that end result?

My maven pom.xml build section for this is

<build>
        <plugins>            
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId> 
                <version>2.5</version>       
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>verishare.App</mainClass>
                        </manifest>
                    </archive>
                </configuration>        
            </plugin>

            <plugin>                
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.5.2</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>verishare.App</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>  <!--this is used for inheritance merges-->
                        <phase>package</phase>  <!--bind to the packaging phase -->
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>            
        </plugins>    
        <resources>
            <resource>
                <directory>src/main/webapp</directory>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
    </build>

Does the above mean anything though? For POMs I've looked at, it appears to be the standard way (of the six you mentioned exist in the wild!) to build fat JARs using Maven.

You can check your produced JAR files, if they contain a META-INF/MANIFEST.MF with a Class-Path entry (to jar files) then you have the type of configuration that worked fine in Java 8, but has to be updated for Java 9+.

I indeed have a META-INF folder containing a MANIFEST.MF file in my compiled fat JAR for this project. So I am definitely subject to this. How would I update this structure to comply with Java 9+?

Because that is all that is broken - we cannot get resources out of a .JAR under JDK 17 and Jetty 11.0.11.

That absolutely works, the two projects I listed above do exactly that.

I don't doubt it, but it remains incredibly complex (as far as I can tell after 90+ hours invested to try and fix the "cannot access JAR resources" Jetty issue) to accomplish in Java 9+ with Jetty. This fact is not documented or well published as far as I can tell, anywhere... several replies and resources referenced (including your kind assistance above) just lead back to the same reference eventually being fed to WebAppContext - e.g. it always leads back to

jar:file:/usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static

which must be

jar:file:///usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static

as you stated, but which simply does not work.

The upshot of all this is we're spending absurd amounts of time to get Jetty to read resources from the JAR (obviously due to not really having a clue what we're about) but with the massive investment made it is approaching a point where we'll need to simply abandon Jetty entirely, OR simply move all its resources out of the JAR and into the filing system.

Wouldn't that work and be an very much simpler solution? Rather than go through all the apparently highly complex & time consuming work required to literally just get Jetty's WebAppContext class to read a .html and .jsp file out of a JAR...

* Uber-jar with ServletContextHandler example -> https://github.com/jetty-project/embedded-jetty-uber-jar/tree/jetty-11.0.x

* Self executing "live" War File example -> https://github.com/jetty-project/embedded-jetty-live-war/tree/jetty-11.0.x

Accessing Resource from a JAR can be done in a dozen different ways, make sure you use the technique that fits your use case. Eg: ClassLoader.getResource(String) / Class.getResource(String) / zipfs / URLConnection / ServletContext.getResource() / etc ...

That's the problem. It can be done in a dozen different ways, but it seems at least 9 or 10 of those are -actually- the "wrong" way, or will only work in one specific version of Jetty under a specific version of the JVM, preferably JDK 8 or older... comes an update and it all falls apart, as has now happened to us here.

Regarding some of the advice in the prior comment from me, here's another example of WebAppContext and resources in a JAR.

* https://github.com/jetty-project/embedded-jetty-cookbook/blob/jetty-11.0.x/src/main/java/org/eclipse/jetty/cookbook/DefaultServletFileServer.java

I did implement the above, but it just causes a whole new set of problems with the JSP pages we have, e. g. they do not render correctly anymore, some tags are completely ignored, etc. It also breaks the servlets we have running, so none of the APIs work anymore, etc. etc.

And if you notice, this example does not rely on webdefault.xml (like your system), but instead adds the DefaultServlet manually in the embedded mode. You can even do multiple DefaultServlet instances serving content from different locations.

This also worries me - nowhere in my JAR or in my project do I have a "webdefault.xml" file... hehe I cannot get one DefaultServlet to work at all and you imply you can have many... ye gods.

* https://github.com/jetty-project/embedded-jetty-cookbook/blob/jetty-11.0.x/src/main/java/org/eclipse/jetty/cookbook/DefaultServletMultipleBases.java

Thanks, but I'm not even going to try and go there - I just need ONE instance of WebAppContext to work and read resources out of the JAR it is embeded it, and so far we've been failing spectacularly at even just that - which is as far as I can tell a pretty simple, basic way to use Jetty (or so I thought.)

You could even use a Jetty ResourceCollection to serve multiple source directories on the same url-pattern, have at it.

The stuff of nightmares. I think I'll pass.

An alternative is to simply not fight jar-with-dependencies behavior changes and just use your war file normally. Using a normal jetty-home/jetty-base split instead? (doesn't help with your IDE concern, but it would fix your jar-with-dependencies concern)

That is yet another concern - I don't have a WAR file, I end up with a JAR file... which is all built and handled automatically by Maven.

Some kind of semantic terminology I don't get? WAR vs. JAR?

What is a "jetty-home/jetty-base split"? How is that implemented?

Will try and get permission to spend more time on this, but I strongly suspect at this point I will simply be forced by the business side to give up and start a complete emergency rewrite of the whole system since we centrally depend on Jetty to get commands and data into and out of the system.

(Or, since everything works EXCEPT reading resources out of the JAR start investigating if it is possible to simply move all the JSP files out of the JAR and into the filing system.)

Thanks again - I'm clearly totally out of my depth and our entire 7 year old Jetty-based project is built on assumptions and a design that was actually invalid and built on shaky concepts from the very start.

Really appreciate the replies and time spent by you!

Stefan

StefanViljoen commented 2 years ago

Jetty is the frontend to about 98 APIs running in this system, this seems to imply I'll need to completely rewrite every single one of those, plus the entire HTML galaxy of the project (about 100 distinct JSP pages / beans, all reliant on Jetty to parse and serve the JSP logic and content.)

The only rewrite would be for the Jetty 11 and its use of Jakarta EE 9 and the namespace change.

I don't understand... as I've found, -everything- with JDK 17, Jetty 11.0.11 works perfectly as-is - as long as I stay inside the NetBeans 14 IDE. You've explained why that is the case, yet here you state a rewrite would have to be done for Jetty 11 and if I use the Jakarta EE 9 artifacts - we do use them already, and it works as is in Netbeans 14, with JDK17 and Jetty 11.0.11?

Cause we did not rewrite anything and it works - as long as we stay in Netbeans 14 - but I suppose you mean "they will need to be rewritten to work in the detached fat JAR"?

I therefore again suspect once the code has been made "detached JAR with Jetty 11.0.11 and JDK 17" compatible, that logically means it will no longer run or work inside NetBeans 14 (or any other Java IDE)? Since IDE-level usability of newer Jetty versions and JAR usability of newer Jetty versions appear to be mutually exclusive things. I'm fine with that though, but obviously it is yet more complexity heaped upon something already extremely complex - e. g. now we will have to start maintaining two branches for the Jetty-based project - one, code that works in an IDE and can be developed on and debugged there, and a completely different branch that is "JAR-able" and can run outside the IDE.

This seems pointlessly complex and an implies a huge amount of highly technical work (done by "expensive" devs due to the extremely high level of Java competence and experience clearly required to work with Jetty reliably) .

I'm probably just misunderstanding you again or putting my ignorance of how Jetty and Java itself works on display.

If you go to Jetty 12, then you'll have a different rewrite to not use deprecated methods in the servlet spec (they have been deprecated for a while, and are now removed in Jakarta EE 10, which will ship with Jetty 12)

See my previous post. This is seriously scary - this implies we'll -just- have it working (maybe, jury's still out) with Jetty 11, and JDK17, then we have to immediately start another round of re-engineering as all our servlet functionality (and therefore our business-critical APIs) will collapse completely (again) in Jetty 12... this is the kind of stuff that causes apoplexy in management on the business side, since they are paying for all these hours (and years) of dev already invested in using Jetty.

Note, that if you move to Jetty 11, these JSP files will need to be touched / updated to satisfy the Jakarta "big bang" to use the new namespaces. (and to use the new XML schema locations for your TLDs)

See above, I don't get this. We use Jetty 11.0.11 under JDK 17 inside the Netbeans IDE with no modifications and no problems. We -are- using Jakrata - each implementation we have of the handleRequest interface starts off with

`` package verishare.api;

import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; ``

or is this not what you mean?

E. g. we left every .jsp file exactly as is under Jetty 11.0.11 and JDK 17, and it all still works perfectly, as long we run the code inside the NetBeans 14 IDE.

The old javax.* namespace for EE libs is dead, now they are on jakarta.*. If you use Spring, know that Spring 6 will be moving whole-hog to this new namespace as well.

Ok...? Not sure what the impact of that is on my currenty setup as it works perfectly inside Netbeans 14.

Literally the only problem we have is that instances of the Jetty 10+ WebAppContext class won't parse

jar:file:///usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static

references, and returns a 404 if a resource in that folder is requested in a web-browser pointed at the Jetty instance running from a fat JAR in Linux.

That is what is so confusing - apparently there is a galaxy of complexity we have to manage to fix problems we are SUPPOSED to be having that we simply don't have - it just works as long as we stay inside the IDE - and apparently (again, if I understand you right, which I doubt, given my limited knowledge of Jetty -and- Java) to run Jetty from a JAR, you DO need to account for that galaxy of underlying complexity... it just doesn't make sense.

Thanks again.

lorban commented 2 years ago

@StefanViljoen

Jetty 11 has a test that ensures serving static content from a jar:file: URI works: https://github.com/eclipse/jetty.project/blob/jetty-11.0.x/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java#L270

I also tried following your instructions and I could not reproduce your problem: I created a class file that starts Jetty as you've shown, serving static files from a subfolder of the jar file, packaging that as a fat jar with the assembly plugin and it all seems to work just fine.

Could you please try turning on DEBUG logs for org.eclipse.jetty, reproduce your problem and attach the generated log file to this issue? Hopefully that should help us figuring our why Jetty is responding with 404 in your case while you're expecting 200.

StefanViljoen commented 2 years ago

@StefanViljoen

Jetty 11 has a test that ensures serving static content from a jar:file: URI works: https://github.com/eclipse/jetty.project/blob/jetty-11.0.x/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java#L270

I also tried following your instructions and I could not reproduce your problem: I created a class file that starts Jetty as you've shown, serving static files from a subfolder of the jar file, packaging that as a fat jar with the assembly plugin and it all seems to work just fine.

Could you please try turning on DEBUG logs for org.eclipse.jetty, reproduce your problem and attach the generated log file to this issue? Hopefully that should help us figuring our why Jetty is responding with 404 in your case while you're expecting 200.

@lorban

Good day sir, thank you for replying!

Jetty 11 has a test that ensures serving static content from a jar:file: URI works: https://github.com/eclipse/jetty.project/blob/jetty-11.0.x/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java#L270

Ok... does that test imply running the produced JAR under JDK17 with Jetty 11.0.11 outside the IDE? E. g. tests are usually IDE driven... and execute in the realm of the IDE's "view" of the local configured JRE.

I'll take a look at the link you posted now and see if I can implement that in my setup and what happens.

I also tried following your instructions and I could not reproduce your problem: I created a class file that starts Jetty as you've shown, serving static files from a subfolder of the jar file, packaging that as a fat jar with the assembly plugin and it all seems to work just fine.

Did you check if you run it outside your IDE, it does function? Because I get the same result you do - as long as I stay inside the Netbeans 14 IDE in Windows and run the code from there, it works perfectly with no exceptions or problems. Web content containing JSP, HTML, JS etc. all works 100%, including all our Jetty ServletContext instances serving out our APIs.

Deploy the code to a detached JRE under Linux and that is where it malfunctions.

That is literally my only issue - with Jetty 11.0.11 under a JDK 17 JRE instannce, outside the Netbeans 14 IDE, the instance of WebAppContext cannot parse the JAR-based resources that describe the web functionality of the application by using an instance of the WebAppContext class.

I've found that the reference passed to the instance of the WebAppContext class if the code is run in the NetBeans 14 IDE using Maven is

file:///D:/Projects/verdi_2/target/classes/static/,AVAILABLE}{file:/D:/Projects/verdi_2/target/classes/static}

whereas if the code is run from the fat JAR in a detached JDK 17 JRE (separate from the Netbeans 14 IDE + JDK 17 combination) in Linux (for example), the reference passed to the instance of the WebAppContext class becomes

jar:file://usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static

which is where the 404 then happens. /static does exist as a folder in the packaged JAR, and does contain the .HTML, .JSP, .js etc. files the system relies on.

Could you please try turning on DEBUG logs for org.eclipse.jetty, reproduce your problem and attach the generated log file to this issue? Hopefully that should help us figuring our why Jetty is responding with 404 in your case while you're expecting 200.

I've tried to turn on debugging, but I can see absolutely no output being generated, at all to Stderr or otherwise.

Do I need some kind of "debug-enabled" version of the Jetty packages - how do I turn on the DEBUG log?

I have Log4J2 installed and working, and instantiated in this class, can you explain or point me to where I can find out how to get Jetty to write the logs you need via Log4J2?

Or failing that even just how to get it to dump the logs to a file on disc?

Thank you VERY much for your help!

Kind regards

Stefan

StefanViljoen commented 2 years ago

@lorban I've tried now to implement your test's code at

https://github.com/eclipse/jetty.project/blob/jetty-11.0.x/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java#L270

to test (I assume this is one thing you want me to try?)

However, I seem to be lacking some dependencies to even minimally try to emulate what you do to establish that jar:///file resources work in that test.

Here's my code so far, derived from line 270 of your test that demonstrates jar:///file functionality:

``

public boolean startJetty(Server server) throws Exception, InterruptedException { boolean retVal = false;

    try {
        server = new Server(AppSettings.getJettyServerPort());

        jettyServer = server;

        ServletContextHandler context = null;

        File extraJarResources = MavenTestingUtils.getTestResourceFile(ODD_JAR);
        URL[] urls = new URL[]{extraJarResources.toURI().toURL()};

        ClassLoader parentClassLoader = Thread.currentThread().getContextClassLoader();
        URLClassLoader extraClassLoader = new URLClassLoader(urls, parentClassLoader);

        context = new ServletContextHandler();

        URL extraResource = context.getClassLoader().getResource("static/index.html");
        String extraResourceBaseString = extraResource.toURI().toASCIIString();
        extraResourceBaseString = extraResourceBaseString.substring(0, extraResourceBaseString.length() - "/index.html".length());

        ServletHolder defholder = context.addServlet(DefaultServlet.class, "/static/*");
        defholder.setInitParameter("resourceBase", extraResourceBaseString);
        defholder.setInitParameter("pathInfoOnly", "true");
        defholder.setInitParameter("dirAllowed", "true");
        defholder.setInitParameter("redirectWelcome", "false");
        defholder.setInitParameter("gzip", "false");

        server.setHandler(context);

        server.setStopAtShutdown(true);
        server.setStopTimeout(0x2710L);

        server.start();

        retVal = true;
    } catch (InterruptedException iex) {
        localLogger.error((String) logEntryRefNumLocal.get() + "InterrupedException in WebHost.java startJetty method.", iex);

        retVal = false;

        throw iex;
    } catch (RuntimeException rex) {
        localLogger.error((String) logEntryRefNumLocal.get() + "Runtime  exception in WebHost.java startJetty method.", rex);

        retVal = false;

        throw rex;
    } catch (Exception ex) {
        localLogger.error((String) logEntryRefNumLocal.get() + "General exception in WebHost.java startJetty method.", ex);

        retVal = false;

        throw ex;
    }

    return retVal;
}

``

However these lines

`` File extraJarResources = MavenTestingUtils.getTestResourceFile(ODD_JAR); URL[] urls = new URL[]{extraJarResources.toURI().toURL()};

``

cannot be compiled a I have no "MavenTestingUtils" dependancy available that implements a getTestResourceFile method.

What is "ODD_JAR" ?

This is required by your code for the

URLClassLoader extraClassLoader = new URLClassLoader(urls, parentClassLoader);

line to be able to compile.

Or am I missing the entire point?

I'm trying to emulate how you manage in your test to access the file:///jar resource here in my environment and see what happens. As you can see both you @lorban and @joakime state the file:///jar resources can be accessed in Jetty 10+ and I'm trying to get your code running here to see what happens if I have letter-correct Java code for such a reference on my side and run it here...

Thanks again.

Stefan

StefanViljoen commented 2 years ago

@ lorban

I also tried following your instructions and I could not reproduce your problem: I created a class file that starts Jetty as you've shown, serving static files from a subfolder of the jar file, packaging that as a fat jar with the assembly plugin and it all seems to work just fine.

Would you mind sharing the method you did the above in?

I want to see if I implement it EXACTLY like you do on my side, it makes any difference.

It is getting to be an extremely desperate situation on my side, 98+ total hours of development invested in this already to get embedded Jetty in our use case to read HTML, JS, etc. resources out of a JAR. Managers here want to pull the plug on the entire Jetty-based ecosystem we have and commence a complete redevelopment of the entire Jetty-dependant system from scratch (and consider the 7 years spent so far on development of this Jetty based project as a total dead loss.)

Thx

lorban commented 2 years ago

I've created a project over here: https://github.com/lorban/jetty-fatjar-static-resource-serving

Simply building it with mvn clean package then starting it with java -jar target/reproducer-8549-1.0-SNAPSHOT-jar-with-dependencies.jar will make Jetty listen on port 8080 and serve the static files that are in the jar's /static folder.

joakime commented 2 years ago

I don't understand... as I've found, -everything- with JDK 17, Jetty 11.0.11 works perfectly as-is - as long as I stay inside the NetBeans 14 IDE. You've explained why that is the case, yet here you state a rewrite would have to be done for Jetty 11 and if I use the Jakarta EE 9 artifacts - we do use them already, and it works as is in Netbeans 14, with JDK17 and Jetty 11.0.11?

Cause we did not rewrite anything and it works - as long as we stay in Netbeans 14 - but I suppose you mean "they will need to be rewritten to work in the detached fat JAR"?

I therefore again suspect once the code has been made "detached JAR with Jetty 11.0.11 and JDK 17" compatible, that logically means it will no longer run or work inside NetBeans 14 (or any other Java IDE)? Since IDE-level usability of newer Jetty versions and JAR usability of newer Jetty versions appear to be mutually exclusive things. I'm fine with that though, but obviously it is yet more complexity heaped upon something already extremely complex - e. g. now we will have to start maintaining two branches for the Jetty-based project - one, code that works in an IDE and can be developed on and debugged there, and a completely different branch that is "JAR-able" and can run outside the IDE.

This seems pointlessly complex and an implies a huge amount of highly technical work (done by "expensive" devs due to the extremely high level of Java competence and experience clearly required to work with Jetty reliably) .

I'm probably just misunderstanding you again or putting my ignorance of how Jetty and Java itself works on display.

Your NetBeans 14 IDE likely has too many dependencies that are irrelevant now once you crossed into the Jakarta EE 9 namespace. Dependencies that are literally never used by anything at runtime.

Copy this class into your project, put it somewhere nearby where you have the Jetty code, and run it from your IDE.

package cloader;

import java.net.URL;
import java.util.Enumeration;

public class WhereIsThisComingFrom
{
    public static void main(String[] args)
    {
        System.out.printf("Java Runtime : %s %s%n",
            System.getProperty("java.runtime.name"),
            System.getProperty("java.runtime.version"));

        ClassLoader cl = Thread.currentThread().getContextClassLoader();

        locate(cl, "javax/servlet/ServletContext.class");
        locate(cl, "jakarta/servlet/ServletContext.class");
    }

    public static void locate(ClassLoader cl, Class<?> clazz)
    {
        String classAsResource = clazz.getName().replace('.', '/') + ".class";
        locate(cl, classAsResource);
    }

    public static void locate(ClassLoader cl, String resourceName)
    {
        try
        {
            Enumeration<URL> urls = cl.getResources(resourceName);
            System.out.printf("Looking for: %s%n", resourceName);
            int count = 0;
            while (urls.hasMoreElements())
            {
                URL url = urls.nextElement();
                System.out.printf(" - Found: %s%n", url.toExternalForm());
                count++;
            }
            System.out.printf(" Found %d times%n", count);
        }
        catch (Throwable t)
        {
            System.out.printf("Whoops: cannot locate: %s%n", resourceName);
            t.printStackTrace();
        }
    }
}

If you get responses on javax.servlet.ServletContext, then your list of dependencies is bad for Jakarta EE 9 (what Jetty 11.x runs on), take strides to eliminate those dependencies from your IDE. If you ONLY get jakarta.servlet.ServletContext, then you are good to go.

If you go to Jetty 12, then you'll have a different rewrite to not use deprecated methods in the servlet spec (they have been deprecated for a while, and are now removed in Jakarta EE 10, which will ship with Jetty 12)

See my previous post. This is seriously scary - this implies we'll -just- have it working (maybe, jury's still out) with Jetty 11, and JDK17, then we have to immediately start another round of re-engineering as all our servlet functionality (and therefore our business-critical APIs) will collapse completely (again) in Jetty 12... this is the kind of stuff that causes apoplexy in management on the business side, since they are paying for all these hours (and years) of dev already invested in using Jetty.

Absolutely what it means. This was announced several years in advance, and got feedback from the community at large. The overwhelming majority of the community agreed that this was necessary.

You can evaluate now what this change will mean to you. Turn on, in your IDE, warnings/errors for use of deprecated methods. This behavior, of deprecating, and then later eliminating code is common in the JVM, even the Java Classes themselves are undergoing this right now (Eg: See JEP-411 with regards to the JVM SecurityManager, which has now been deprecated, and in current Java JVMs is now neutered and is essentially a noop, and in an upcoming JVM will be removed)

Note, that if you move to Jetty 11, these JSP files will need to be touched / updated to satisfy the Jakarta "big bang" to use the new namespaces. (and to use the new XML schema locations for your TLDs)

See above, I don't get this. We use Jetty 11.0.11 under JDK 17 inside the Netbeans IDE with no modifications and no problems. We -are- using Jakrata - each implementation we have of the handleRequest interface starts off with

`` package verishare.api;

import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; ``

or is this not what you mean?

This is an appropriate level of change for Jakarta EE 9, and Jakarta Servlet 5.

E. g. we left every .jsp file exactly as is under Jetty 11.0.11 and JDK 17, and it all still works perfectly, as long we run the code inside the NetBeans 14 IDE.

JSP's, for example, would need updates for things like ...

<!-- changed -->
<%@page import="jakarta.servlet.htt.HttpSession"/>
<!-- removed -->
<jsp:plugin> 
<jsp:params>
<jsp:fallback>

If you wrote your own tags/taglibs, you'll have to check if the new EL discovery methods are necessary for you. If your taglibs reference XML from the standard taglib, the URLs that define those references have changed. If your taglibs have previously used now deprecated methods and are now causing you issues when they stop doing what they used to do.

The old javax.* namespace for EE libs is dead, now they are on jakarta.*. If you use Spring, know that Spring 6 will be moving whole-hog to this new namespace as well.

Ok...? Not sure what the impact of that is on my currenty setup as it works perfectly inside Netbeans 14.

Literally the only problem we have is that instances of the Jetty 10+ WebAppContext class won't parse

Yep, that makes total sense.

Jetty 10 is Jakarta EE 8 / Javax Servlet 4 (aka javax.servlet.*) Jetty 11 is Jakarta EE 9 / Jakarta Servlet 5 (aka jakarta.servlet.*)

Do not mix versions of Jetty, all of your Jetty dependencies must be aligned on the same version.

You've been talking about Jetty 11.x mostly, so stick with that, don't even look at Jetty 10.x

You can use the jetty-bom in your maven build to version align things if you need to.

jar:file:///usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static

references, and returns a 404 if a resource in that folder is requested in a web-browser pointed at the Jetty instance running from a fat JAR in Linux.

That is what is so confusing - apparently there is a galaxy of complexity we have to manage to fix problems we are SUPPOSED to be having that we simply don't have - it just works as long as we stay inside the IDE - and apparently (again, if I understand you right, which I doubt, given my limited knowledge of Jetty -and- Java) to run Jetty from a JAR, you DO need to account for that galaxy of underlying complexity... it just doesn't make sense.

A WebAppContext in the embedded-jetty that is kicked off by jetty-start depends on configuration. Configuration you seem to be lacking. For example, the WebAppContext has a "defaults descriptor", which defines things like the DefaultServlet, the JspServlet, mime-types, security roles, TRACE method prevention, etc...

If this doesn't exist in your configuration of your WebAppContext, then you have none of the "default" behaviors, and you wind up with a WebAppContext that cannot serve static files, cannot serve JSPs, etc. Basically the "default" WebAppContext in your scenario would only have a Default404Servlet which returns 404 on any request that doesn't match a url-pattern for your Servlets.

This webdefault.xml can be found in the jetty-webapp-11.<ver>.jar file in the location org/eclipse/jetty/webapp/webdefault.xml.

This isn't being found, and your "jar-with-dependencies" is a likely culprit. You are using the assembly plugin to build your "jar-with-dependencies", with the default descriptor of <descriptorRef>jar-with-dependencies</descriptorRef>. See: https://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html#jar-with-dependencies

That is WOEFULLY broken in your build.

As the assembly plugin does not:

Back in Java 8, you didn't have to worry about module-info.class or JEP-238 and Multi-Release JAR files. Back in Jetty 9, and Javax Servlet 3.1, you didn't have to worry about META-INF/services files. You are now using more modern libs, you now must handle them properly.

You should have moved to the maven-shade-plugin ages ago, as that will handle the things that the assembly plugin simply cannot handle.

This is an example of using the maven-shade-plugin:

Look at this configuration, see how it ...

Lets see what all of this damage from maven-assembly-plugin has caused you, do this ...

In your Embedded Jetty code that starts the Server object, add this one line of code and report back the dump it shows on your console.

server.setDumpAfterStart(true); // <-- this line (make sure it happens at some point BEFORE server.start)
server.start();
StefanViljoen commented 2 years ago

Your NetBeans 14 IDE likely has too many dependencies that are irrelevant now once you crossed into the Jakarta EE 9 namespace. Dependencies that are literally never used by anything at runtime.

Copy this class into your project, put it somewhere nearby where you have the Jetty code, and run it from your IDE.

.
.
.

If you get responses on javax.servlet.ServletContext, then your list of dependencies is bad for Jakarta EE 9 (what Jetty 11.x runs on), take strides to eliminate those dependencies from your IDE. If you ONLY get jakarta.servlet.ServletContext, then you are good to go.

Ok, I got this back:

Looking for: javax/servlet/ServletContext.class
 Found 0 times
Looking for: jakarta/servlet/ServletContext.class
 - Found: jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/toolchain/jetty-jakarta-servlet-api/5.0.2/jetty-jakarta-servlet-api-5.0.2.jar!/jakarta/servlet/ServletContext.class
 Found 1 times

So that at least is good to go.

management on the business side, since they are paying for all these hours (and years) of dev already invested in using Jetty.

Absolutely what it means. This was announced several years in advance, and got feedback from the community at large. The overwhelming majority of the community agreed that this was necessary.

That is what I suspected was going on. You gotta love democracy.

You can evaluate now what this change will mean to you. Turn on, in your IDE, warnings/errors for use of deprecated methods. This behavior, of deprecating, and then later eliminating code is common in the JVM, even the Java Classes themselves are undergoing this right now (Eg: See JEP-411 with regards to the JVM SecurityManager, which has now been deprecated, and in current Java JVMs is now neutered and is essentially a noop, and in an upcoming JVM will be removed)

Hmm ok my version of Netbeans is apparently set to HTML strikethrough any deprecated code - cannot spot "struck through" code anywhere in the Jetty setup code or in most of the APIs code that run through Jetty.

Note, that if you move to Jetty 11, these JSP files will need to be touched / updated to satisfy the Jakarta "big bang" to use the new namespaces. (and to use the new XML schema locations for your TLDs)

See above, I don't get this. We use Jetty 11.0.11 under JDK 17 inside the Netbeans IDE with no modifications and no problems. We -are- using Jakrata - each implementation we have of the handleRequest interface starts off with package verishare.api; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; or is this not what you mean?

This is an appropriate level of change for Jakarta EE 9, and Jakarta Servlet 5.

Phew. One thing is correct! Yay.

E. g. we left every .jsp file exactly as is under Jetty 11.0.11 and JDK 17, and it all still works perfectly, as long we run the code inside the NetBeans 14 IDE.

JSP's, for example, would need updates for things like ...

<!-- changed -->
<%@page import="jakarta.servlet.htt.HttpSession"/>
<!-- removed -->
<jsp:plugin> 
<jsp:params>
<jsp:fallback>

Ok... my JSPs currently look like this at the top (and they all currently work correctly, inside the Netbeans 14 IDE, with all the above in consideration as well):

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id="statusDataSync" scope="page" class="verishare.AppStatusDataSync"/>
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Verdi Datasync Status</title>
.
.
.
</head>
<body>
.
.
.
</body>
</html>

If you wrote your own tags/taglibs, you'll have to check if the new EL discovery methods are necessary for you. If your taglibs reference XML from the standard taglib, the URLs that define those references have changed. If your taglibs have previously used now deprecated methods and are now causing you issues when they stop doing what they used to do.

We've never written our own tags as far as I now... all JSPs still work currently under Jetty 11.0.11 as long as we run from the Netbeans 14 IDE.

The old javax.* namespace for EE libs is dead, now they are on jakarta.*. If you use Spring, know that Spring 6 will be moving whole-hog to this new namespace as well.

Ok...? Not sure what the impact of that is on my currenty setup as it works perfectly inside Netbeans 14. Literally the only problem we have is that instances of the Jetty 10+ WebAppContext class won't parse

Yep, that makes total sense.

Ok so we're probably good on that.

Jetty 10 is Jakarta EE 8 / Javax Servlet 4 (aka javax.servlet.*) Jetty 11 is Jakarta EE 9 / Jakarta Servlet 5 (aka jakarta.servlet.*)

Do not mix versions of Jetty, all of your Jetty dependencies must be aligned on the same version.

Roger that. I just used that terminology "Jetty 10+" for just that - my POM.xml explicitly specifies

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>verishare</groupId>
    <artifactId>verdi</artifactId>
    <version>12-JDK17</version>
    <packaging>jar</packaging>

    <name>verdi</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- Adapt this to a version found on
           http://central.maven.org/maven2/org/eclipse/jetty/jetty-maven-plugin/
        -->
        <!--<jettyVersion>9.2.2.v20140723</jettyVersion>-->
        <!--<jettyVersion>9.2.23.v20171218</jettyVersion>-->
        <!--<jettyVersion>9.4.48.v20220622</jettyVersion>--> <!--Java 17 Netbeans 14 working-->
        <!--<jettyVersion>10.0.11</jettyVersion>--> <!-- Working as of 2022-08-26 -->
        <!--<jettyVersion>11.0.0</jettyVersion>-->
        <jettyVersion>11.0.11</jettyVersion>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

and then

<dependency>
            <groupId>org.eclipse.jetty.websocket</groupId>
            <artifactId>websocket-jetty-server</artifactId>
            <version>${jettyVersion}</version>
        </dependency>        
        <dependency>
            <groupId>org.eclipse.jetty.websocket</groupId>
            <artifactId>websocket-jetty-client</artifactId>
            <version>${jettyVersion}</version>
        </dependency>
<dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>${jettyVersion}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>${jettyVersion}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>${jettyVersion}</version>
        </dependency>        
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-annotations</artifactId>
            <version>${jettyVersion}</version>
        </dependency>        
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>apache-jsp</artifactId>
            <version>${jettyVersion}</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>apache-jstl</artifactId>
            <version>11.0.0</version>        
        </dependency>

You've been talking about Jetty 11.x mostly, so stick with that, don't even look at Jetty 10.x

Roger that.

You can use the jetty-bom in your maven build to version align things if you need to.

* https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-bom/11.0.11/jetty-bom-11.0.11.pom

Ok that will be my next port of call.

jar:file:///usr/src/verdi/verdi-12-JDK17-jar-with-dependencies.jar!/static references, and returns a 404 if a resource in that folder is requested in a web-browser pointed at the Jetty instance running from a fat JAR in Linux. That is what is so confusing - apparently there is a galaxy of complexity we have to manage to fix problems we are SUPPOSED to be having that we simply don't have - it just works as long as we stay inside the IDE - and apparently (again, if I understand you right, which I doubt, given my limited knowledge of Jetty -and- Java) to run Jetty from a JAR, you DO need to account for that galaxy of underlying complexity... it just doesn't make sense.

A WebAppContext in the embedded-jetty that is kicked off by jetty-start depends on configuration. Configuration you seem to be lacking.

Ok. That makes sense.

For example, the WebAppContext has a "defaults descriptor", which defines things like the DefaultServlet, the JspServlet, mime-types, security roles, TRACE method prevention, etc...

* https://github.com/eclipse/jetty.project/blob/jetty-11.0.11/jetty-webapp/src/main/config/etc/webdefault.xml

If this doesn't exist in your configuration of your WebAppContext, then you have none of the "default" behaviors, and you wind up with a WebAppContext that cannot serve static files, cannot serve JSPs, etc. Basically the "default" WebAppContext in your scenario would only have a Default404Servlet which returns 404 on any request that doesn't match a url-pattern for your Servlets.

That is exactly what happens - if the JAR is run outside of the IDE.

This webdefault.xml can be found in the jetty-webapp-11.<ver>.jar file in the location org/eclipse/jetty/webapp/webdefault.xml.

Ok, so I take this file and copy it out of that JAR into my project somewhere (where?) and set it up?

This isn't being found, and your "jar-with-dependencies" is a likely culprit. You are using the assembly plugin to build your "jar-with-dependencies", with the default descriptor of <descriptorRef>jar-with-dependencies</descriptorRef>. See: https://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html#jar-with-dependencies

That is WOEFULLY broken in your build.

Ok.

As the assembly plugin does not:

* merge `META-INF/services` files (CRITICAL STEP)

* handle the nuances of `module-info.class` (CRITICAL STEP)

* handle JEP-238 Multi-Release JAR files (CRITICAL STEP)

* handle duplicate classes correctly (Optional Step, your dependencies will determine if you need to deal with this or not)

gulp

Back in Java 8, you didn't have to worry about module-info.class or JEP-238 and Multi-Release JAR files. Back in Jetty 9, and Javax Servlet 3.1, you didn't have to worry about META-INF/services files. You are now using more modern libs, you now must handle them properly.

Ok.

You should have moved to the maven-shade-plugin ages ago, as that will handle the things that the assembly plugin simply cannot handle.

Ok, I've read of maven-shade-plugin but haven't tried it yet (basically didn't know I needed it) - thanks for letting me know. :)

This is an example of using the maven-shade-plugin:

* https://github.com/jetty-project/embedded-jetty-uber-jar/blob/jetty-11.0.x/pom.xml#L160-L236

Look at this configuration, see how it ...

* Merges `META-INF/services` files with the `org.apache.maven.plugins.shade.resource.ServicesResourceTransformer`

* Excludes `module-info.class` from being in the resulting jar

* Natively handles JEP-238 (no config needed)

* Has special configuration for dealing with duplicate classes (see config around `jakarta.websocket:jakarta.websocket-client-api`)

Ok...

Lets see what all of this damage from maven-assembly-plugin has caused you, do this ...

In your Embedded Jetty code that starts the Server object, add this one line of code and report back the dump it shows on your console.

server.setDumpAfterStart(true); // <-- this line (make sure it happens at some point BEFORE server.start)
server.start();

Here is what it shows...

2022-09-07 15:46:17.770 INFO  WebHost - sl0ok4t12gki - Actually start the Jetty Server... 
[main] INFO org.eclipse.jetty.server.Server - jetty-11.0.11; built: 2022-06-21T21:42:55.454Z; git: 58487315cb75e0f5c81cc6fa50096cbeb3b9554e; jvm 17.0.4.1+1-LTS-2
[main] INFO org.eclipse.jetty.server.session.DefaultSessionIdManager - Session workerName=node0
[main] INFO org.eclipse.jetty.server.handler.ContextHandler - Started o.e.j.s.ServletContextHandler@231baf51{/api,null,AVAILABLE}
[main] INFO org.eclipse.jetty.server.handler.ContextHandler - Started o.e.j.s.ServletContextHandler@73877e19{/conf,null,AVAILABLE}
[main] INFO org.eclipse.jetty.server.handler.ContextHandler - Started o.e.j.s.ServletContextHandler@5bfc257{/tmpdata,null,AVAILABLE}
[main] INFO org.eclipse.jetty.server.handler.ContextHandler - Started o.e.j.w.WebAppContext@769d513{/,file:///D:/Projects/verdi_2/target/classes/static/,AVAILABLE}{file:/D:/Projects/verdi_2/target/classes/static}
[main] INFO org.eclipse.jetty.server.AbstractConnector - Started ServerConnector@35c09b94{HTTP/1.1, (http/1.1)}{0.0.0.0:8086}
[main] INFO org.eclipse.jetty.server.Server - Started Server@29182679{STARTING}[11.0.11,sto=10000] @3119ms
Server@29182679{STARTING}[11.0.11,sto=10000] - STARTING
+= QueuedThreadPool[qtp1495161082]@591e58fa{STARTED,8<=8<=200,i=5,r=-1,q=0}[ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0}] - STARTED
|  +- org.eclipse.jetty.util.thread.ThreadPoolBudget@162b3d47
|  += ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0} - STARTED
|  |  +> threads size=0
|  +> threads size=8
|     +> qtp1495161082-26 TIMED_WAITING tid=26 prio=5 IDLE
|     +> qtp1495161082-29-acceptor-0@5c76950b-ServerConnector@35c09b94{HTTP/1.1, (http/1.1)}{0.0.0.0:8086} RUNNABLE tid=29 prio=3 ACCEPTING
|     +> qtp1495161082-30 TIMED_WAITING tid=30 prio=5 IDLE
|     +> qtp1495161082-32 TIMED_WAITING tid=32 prio=5 IDLE
|     +> qtp1495161082-31 TIMED_WAITING tid=31 prio=5 IDLE
|     +> qtp1495161082-25 TIMED_WAITING tid=25 prio=5 IDLE
|     +> qtp1495161082-27 RUNNABLE tid=27 prio=5 SELECTING
|     +> qtp1495161082-28 RUNNABLE tid=28 prio=5 SELECTING
+= AttributeContainerMap@173f73e7{size=4} - STARTED
|  +@ org.eclipse.jetty.resources.cache = java.util.concurrent.ConcurrentHashMap@9828da6b{size=2}
|  |  +@ file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar = org.eclipse.jetty.util.resource.EmptyResource@43a51d00
|  |  +@ file:///C:/Users/SV/.m2/repository/org/eclipse/jetty/toolchain/jetty-jakarta-servlet-api/5.0.2/jetty-jakarta-servlet-api-5.0.2.jar = org.eclipse.jetty.util.resource.EmptyResource@43a51d00
|  +@ org.eclipse.jetty.server.Request.maxFormContentSize = -1
|  +@ org.eclipse.jetty.webFragments.cache = java.util.concurrent.ConcurrentHashMap@9828da6b{size=2}
|  |  +@ file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar = org.eclipse.jetty.util.resource.EmptyResource@43a51d00
|  |  +@ file:///C:/Users/SV/.m2/repository/org/eclipse/jetty/toolchain/jetty-jakarta-servlet-api/5.0.2/jetty-jakarta-servlet-api-5.0.2.jar = org.eclipse.jetty.util.resource.EmptyResource@43a51d00
|  +@ org.eclipse.jetty.tlds.cache = java.util.concurrent.ConcurrentHashMap@d27414f3{size=2}
|     +@ file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar = java.util.HashSet@ca93d388(size=12)
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/c-1_0-rt.tld
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/permittedTaglibs.tld
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/fmt-1_0-rt.tld
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/scriptfree.tld
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/x.tld
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/c.tld
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/fmt.tld
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/fn.tld
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/sql.tld
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/sql-1_0-rt.tld
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/x-1_0-rt.tld
|     |  +: jar:file:///C:/Users/SV/.m2/repository/org/mortbay/jasper/taglibs-standard/10.0.0-M10/taglibs-standard-10.0.0-M10.jar!/META-INF/c-1_1.tld
|     +@ file:///C:/Users/SV/.m2/repository/org/eclipse/jetty/toolchain/jetty-jakarta-servlet-api/5.0.2/jetty-jakarta-servlet-api-5.0.2.jar = java.util.HashSet@0(size=0)
+= HandlerList@2e23c180{STARTED} - STARTED
|  += o.e.j.s.ServletContextHandler@231baf51{/api,null,AVAILABLE} - STARTED
|  |  += org.eclipse.jetty.server.session.SessionHandler173059685==dftMaxIdleSec=-1 - STARTED
|  |  |  += ServletHandler@499683c4{STARTED} - STARTED
|  |  |  |  +> listeners ServletHandler@499683c4{STARTED} size=0
|  |  |  |  +> filters ServletHandler@499683c4{STARTED} size=0
|  |  |  |  +> filterMappings ServletHandler@499683c4{STARTED} size=0
|  |  |  |  +> servlets ServletHandler@499683c4{STARTED} size=2
|  |  |  |  |  +> verishare.webServer.WebApiServlet-5aa6202e==verishare.webServer.WebApiServlet@6cc11a4c{jsp=null,order=-1,inst=true,async=true,src=EMBEDDED:null,STARTED} - STARTED
|  |  |  |  |  |  +> verishare.webServer.WebApiServlet@25da615a
|  |  |  |  |  +> org.eclipse.jetty.servlet.ServletHandler$Default404Servlet-7a799159==org.eclipse.jetty.servlet.ServletHandler$Default404Servlet@1ade4ebc{jsp=null,order=-1,inst=false,async=true,src=EMBEDDED:null,STARTED} - STARTED
|  |  |  |  |     +> class org.eclipse.jetty.servlet.ServletHandler$Default404Servlet
|  |  |  |  +> servletMappings ServletHandler@499683c4{STARTED} size=2
|  |  |  |  |  +> [/*]=>verishare.webServer.WebApiServlet-5aa6202e
|  |  |  |  |  +> [/]=>org.eclipse.jetty.servlet.ServletHandler$Default404Servlet-7a799159
|  |  |  |  +> durable ServletHandler@499683c4{STARTED} size=1
|  |  |  |     +> verishare.webServer.WebApiServlet-5aa6202e==verishare.webServer.WebApiServlet@6cc11a4c{jsp=null,order=-1,inst=true,async=true,src=EMBEDDED:null,STARTED} - STARTED
|  |  |  |        +> verishare.webServer.WebApiServlet@25da615a
|  |  |  += org.eclipse.jetty.server.session.DefaultSessionCache@4efc25fc[evict=-1,removeUnloadable=false,saveOnCreate=false,saveOnInactiveEvict=false] - STARTED
|  |  |  |  += org.eclipse.jetty.server.session.NullSessionDataStore@7ee3d262[passivating=false,graceSec=3600] - STARTED
|  |  |  +~ DefaultSessionIdManager@396e6d9{STARTED}[worker=node0] - STARTED
|  |  +> No ClassLoader
|  |  +> handler attributes o.e.j.s.ServletContextHandler@231baf51{/api,null,AVAILABLE} size=1
|  |  |  +> org.eclipse.jetty.server.Executor=QueuedThreadPool[qtp1495161082]@591e58fa{STARTED,8<=8<=200,i=5,r=-1,q=0}[ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0}]
|  |  +> context attributes o.e.j.s.ServletContextHandler@231baf51{/api,null,AVAILABLE} size=1
|  |  |  +> org.eclipse.jetty.util.DecoratedObjectFactory=org.eclipse.jetty.util.DecoratedObjectFactory[decorators=1]
|  |  +> initparams o.e.j.s.ServletContextHandler@231baf51{/api,null,AVAILABLE} size=0
|  += o.e.j.s.ServletContextHandler@73877e19{/conf,null,AVAILABLE} - STARTED
|  |  += ServletHandler@5acc9fdf{STARTED} - STARTED
|  |  |  +> listeners ServletHandler@5acc9fdf{STARTED} size=0
|  |  |  +> filters ServletHandler@5acc9fdf{STARTED} size=0
|  |  |  +> filterMappings ServletHandler@5acc9fdf{STARTED} size=0
|  |  |  +> servlets ServletHandler@5acc9fdf{STARTED} size=2
|  |  |  |  +> verishare.webServer.WebPhoneConfigurator-733037==verishare.webServer.WebPhoneConfigurator@f76c6d8f{jsp=null,order=-1,inst=true,async=true,src=EMBEDDED:null,STARTED} - STARTED
|  |  |  |  |  +> verishare.webServer.WebPhoneConfigurator@3a5c2626
|  |  |  |  +> org.eclipse.jetty.servlet.ServletHandler$Default404Servlet-11841b15==org.eclipse.jetty.servlet.ServletHandler$Default404Servlet@c1d79ce5{jsp=null,order=-1,inst=false,async=true,src=EMBEDDED:null,STARTED} - STARTED
|  |  |  |     +> class org.eclipse.jetty.servlet.ServletHandler$Default404Servlet
|  |  |  +> servletMappings ServletHandler@5acc9fdf{STARTED} size=2
|  |  |  |  +> [/*]=>verishare.webServer.WebPhoneConfigurator-733037
|  |  |  |  +> [/]=>org.eclipse.jetty.servlet.ServletHandler$Default404Servlet-11841b15
|  |  |  +> durable ServletHandler@5acc9fdf{STARTED} size=1
|  |  |     +> verishare.webServer.WebPhoneConfigurator-733037==verishare.webServer.WebPhoneConfigurator@f76c6d8f{jsp=null,order=-1,inst=true,async=true,src=EMBEDDED:null,STARTED} - STARTED
|  |  |        +> verishare.webServer.WebPhoneConfigurator@3a5c2626
|  |  +> No ClassLoader
|  |  +> handler attributes o.e.j.s.ServletContextHandler@73877e19{/conf,null,AVAILABLE} size=1
|  |  |  +> org.eclipse.jetty.server.Executor=QueuedThreadPool[qtp1495161082]@591e58fa{STARTED,8<=8<=200,i=5,r=-1,q=0}[ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0}]
|  |  +> context attributes o.e.j.s.ServletContextHandler@73877e19{/conf,null,AVAILABLE} size=1
|  |  |  +> org.eclipse.jetty.util.DecoratedObjectFactory=org.eclipse.jetty.util.DecoratedObjectFactory[decorators=1]
|  |  +> initparams o.e.j.s.ServletContextHandler@73877e19{/conf,null,AVAILABLE} size=0
|  += o.e.j.s.ServletContextHandler@5bfc257{/tmpdata,null,AVAILABLE} - STARTED
|  |  += ServletHandler@e48bf9a{STARTED} - STARTED
|  |  |  +> listeners ServletHandler@e48bf9a{STARTED} size=0
|  |  |  +> filters ServletHandler@e48bf9a{STARTED} size=0
|  |  |  +> filterMappings ServletHandler@e48bf9a{STARTED} size=0
|  |  |  +> servlets ServletHandler@e48bf9a{STARTED} size=2
|  |  |  |  +> verishare.webServer.TempFileServlet-a0a9fa5==verishare.webServer.TempFileServlet@ddae44af{jsp=null,order=-1,inst=true,async=true,src=EMBEDDED:null,STARTED} - STARTED
|  |  |  |  |  +> verishare.webServer.TempFileServlet@7fb33394
|  |  |  |  +> org.eclipse.jetty.servlet.ServletHandler$Default404Servlet-7b208b45==org.eclipse.jetty.servlet.ServletHandler$Default404Servlet@46bdbec8{jsp=null,order=-1,inst=false,async=true,src=EMBEDDED:null,STARTED} - STARTED
|  |  |  |     +> class org.eclipse.jetty.servlet.ServletHandler$Default404Servlet
|  |  |  +> servletMappings ServletHandler@e48bf9a{STARTED} size=2
|  |  |  |  +> [/*]=>verishare.webServer.TempFileServlet-a0a9fa5
|  |  |  |  +> [/]=>org.eclipse.jetty.servlet.ServletHandler$Default404Servlet-7b208b45
|  |  |  +> durable ServletHandler@e48bf9a{STARTED} size=1
|  |  |     +> verishare.webServer.TempFileServlet-a0a9fa5==verishare.webServer.TempFileServlet@ddae44af{jsp=null,order=-1,inst=true,async=true,src=EMBEDDED:null,STARTED} - STARTED
|  |  |        +> verishare.webServer.TempFileServlet@7fb33394
|  |  +> No ClassLoader
|  |  +> handler attributes o.e.j.s.ServletContextHandler@5bfc257{/tmpdata,null,AVAILABLE} size=1
|  |  |  +> org.eclipse.jetty.server.Executor=QueuedThreadPool[qtp1495161082]@591e58fa{STARTED,8<=8<=200,i=5,r=-1,q=0}[ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0}]
|  |  +> context attributes o.e.j.s.ServletContextHandler@5bfc257{/tmpdata,null,AVAILABLE} size=1
|  |  |  +> org.eclipse.jetty.util.DecoratedObjectFactory=org.eclipse.jetty.util.DecoratedObjectFactory[decorators=1]
|  |  +> initparams o.e.j.s.ServletContextHandler@5bfc257{/tmpdata,null,AVAILABLE} size=0
|  += o.e.j.w.WebAppContext@769d513{/,file:///D:/Projects/verdi_2/target/classes/static/,AVAILABLE}{file:/D:/Projects/verdi_2/target/classes/static} - STARTED
|  |  += org.eclipse.jetty.server.session.SessionHandler2140322192==dftMaxIdleSec=1800 - STARTED
|  |  |  += ConstraintSecurityHandler@41bf79da{STARTED} - STARTED
|  |  |  |  +- knownAuthenticatorFactories size=1
|  |  |  |  |  +> org.eclipse.jetty.security.DefaultAuthenticatorFactory@1a891add
|  |  |  |  +- org.eclipse.jetty.security.authentication.BasicAuthenticator@5176d279
|  |  |  |  += HashLoginService@373f7450[admin] - STARTED
|  |  |  |  |  +- org.eclipse.jetty.security.DefaultIdentityService@d74bac4
|  |  |  |  |  += UserStore@5ff90645[users.count=784] - STARTED
|  |  |  |  += ServletHandler@387bf2d9{STARTED} - STARTED
|  |  |  |  |  +> listeners ServletHandler@387bf2d9{STARTED} size=2
|  |  |  |  |  |  +> org.eclipse.jetty.servlet.listener.ELContextCleaner@74aa9c72{src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml} - STARTED
|  |  |  |  |  |  +> org.eclipse.jetty.servlet.listener.IntrospectorCleaner@5c20aab9{src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml} - STARTED
|  |  |  |  |  +> filters ServletHandler@387bf2d9{STARTED} size=0
|  |  |  |  |  +> filterMappings ServletHandler@387bf2d9{STARTED} size=0
|  |  |  |  |  +> servlets ServletHandler@387bf2d9{STARTED} size=2
|  |  |  |  |  |  +> default==org.eclipse.jetty.servlet.DefaultServlet@5c13d641{jsp=null,order=0,inst=true,async=false,src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml,STARTED} - STARTED
|  |  |  |  |  |  |  +> NotAsync:org.eclipse.jetty.servlet.DefaultServlet@4b7c4456
|  |  |  |  |  |  |  +> initParams size=9
|  |  |  |  |  |  |     +> dirAllowed=true
|  |  |  |  |  |  |     +> maxCacheSize=256000000
|  |  |  |  |  |  |     +> maxCachedFileSize=200000000
|  |  |  |  |  |  |     +> welcomeServlets=false
|  |  |  |  |  |  |     +> useFileMappedBuffer=true
|  |  |  |  |  |  |     +> acceptRanges=true
|  |  |  |  |  |  |     +> etags=false
|  |  |  |  |  |  |     +> maxCachedFiles=2048
|  |  |  |  |  |  |     +> redirectWelcome=false
|  |  |  |  |  |  +> jsp==org.eclipse.jetty.jsp.JettyJspServlet@19c47{jsp=null,order=0,inst=true,async=false,src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml,STARTED} - STARTED
|  |  |  |  |  |     +> NotAsync:org.eclipse.jetty.jsp.JettyJspServlet@2c768ada
|  |  |  |  |  |     +> initParams size=4
|  |  |  |  |  |        +> compilerSourceVM=1.8
|  |  |  |  |  |        +> compilerTargetVM=1.8
|  |  |  |  |  |        +> scratchdir=C:\Users\SV\AppData\Local\Temp\jetty-0_0_0_0-8086-static-_-any-14226370079976394059\jsp
|  |  |  |  |  |        +> xpoweredBy=false
|  |  |  |  |  +> servletMappings ServletHandler@387bf2d9{STARTED} size=2
|  |  |  |  |  |  +> [/]=>default
|  |  |  |  |  |  +> [*.jsp, *.jspf, *.jspx, *.xsp, *.JSP, *.JSPF, *.JSPX, *.XSP]=>jsp
|  |  |  |  |  +> durable ServletHandler@387bf2d9{STARTED} size=4
|  |  |  |  |     +> default==org.eclipse.jetty.servlet.DefaultServlet@5c13d641{jsp=null,order=0,inst=true,async=false,src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml,STARTED} - STARTED
|  |  |  |  |     |  +> NotAsync:org.eclipse.jetty.servlet.DefaultServlet@4b7c4456
|  |  |  |  |     |  +> initParams size=9
|  |  |  |  |     |     +> dirAllowed=true
|  |  |  |  |     |     +> maxCacheSize=256000000
|  |  |  |  |     |     +> maxCachedFileSize=200000000
|  |  |  |  |     |     +> welcomeServlets=false
|  |  |  |  |     |     +> useFileMappedBuffer=true
|  |  |  |  |     |     +> acceptRanges=true
|  |  |  |  |     |     +> etags=false
|  |  |  |  |     |     +> maxCachedFiles=2048
|  |  |  |  |     |     +> redirectWelcome=false
|  |  |  |  |     +> jsp==org.eclipse.jetty.jsp.JettyJspServlet@19c47{jsp=null,order=0,inst=true,async=false,src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml,STARTED} - STARTED
|  |  |  |  |     |  +> NotAsync:org.eclipse.jetty.jsp.JettyJspServlet@2c768ada
|  |  |  |  |     |  +> initParams size=4
|  |  |  |  |     |     +> compilerSourceVM=1.8
|  |  |  |  |     |     +> compilerTargetVM=1.8
|  |  |  |  |     |     +> scratchdir=C:\Users\SV\AppData\Local\Temp\jetty-0_0_0_0-8086-static-_-any-14226370079976394059\jsp
|  |  |  |  |     |     +> xpoweredBy=false
|  |  |  |  |     +> org.eclipse.jetty.servlet.listener.ELContextCleaner@74aa9c72{src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml} - STARTED
|  |  |  |  |     +> org.eclipse.jetty.servlet.listener.IntrospectorCleaner@5c20aab9{src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml} - STARTED
|  |  |  |  +~ org.eclipse.jetty.security.DefaultIdentityService@d74bac4
|  |  |  |  +> roles size=1
|  |  |  |  |  +> user
|  |  |  |  +> constraints size=3
|  |  |  |     +> org.eclipse.jetty.security.ConstraintMapping@c1fca2a
|  |  |  |     +> org.eclipse.jetty.security.ConstraintMapping@5533dc72
|  |  |  |     +> org.eclipse.jetty.security.ConstraintMapping@7c447c76
|  |  |  += org.eclipse.jetty.server.session.DefaultSessionCache@64fc097e[evict=-1,removeUnloadable=false,saveOnCreate=false,saveOnInactiveEvict=false] - STARTED
|  |  |  |  += org.eclipse.jetty.server.session.NullSessionDataStore@1640c151[passivating=false,graceSec=3600] - STARTED
|  |  |  +~ DefaultSessionIdManager@396e6d9{STARTED}[worker=node0] - STARTED
|  |  += ErrorPageErrorHandler@5d5b5fa7{STARTED} - STARTED
|  |  +- java:comp org.eclipse.jetty.jndi.NamingContext@2a32fb6[name=comp,parent=org.eclipse.jetty.jndi.NamingContext@6107165,bindings.size=1]
|  |  |  +@ env = org.eclipse.jetty.jndi.NamingContext@164a62bf[name=env,parent=org.eclipse.jetty.jndi.NamingContext@2a32fb6,bindings.size=0]
|  |  += ServletContainerInitializerStarter@11ebb1b6{STARTED} - STARTED
|  |  |  += ContainerInitializer{org.eclipse.jetty.apache.jsp.JettyJasperInitializer,interested=[],applicable=[],annotated=[]} - STARTED
|  |  |  += ContainerInitializer{org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer,interested=[],applicable=[],annotated=[]} - STARTED
|  |  += WebSocketServerComponents@f3021cb{STARTED} - STARTED
|  |  |  +~ InflaterPool@4aaae508{STARTED,size=0,capacity=200} - STARTED
|  |  |  +~ DeflaterPool@6009bea{STARTED,size=0,capacity=200} - STARTED
|  |  |  +- MappedByteBufferPool@7bc6d27a{maxQueueLength=-1, factor=1024}
|  |  |  |  +> java.util.ArrayList@7498ce09(size=4)
|  |  |  |     +: HeapMemory: 0/533200896
|  |  |  |     +: DirectMemory: 0/533200896
|  |  |  |     +: Indirect Buckets size=0
|  |  |  |     +: Direct Buckets size=0
|  |  |  +- org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry@75769ab0
|  |  |  |  +: class org.eclipse.jetty.websocket.core.internal.FragmentExtension
|  |  |  |  +: class org.eclipse.jetty.websocket.core.internal.FrameCaptureExtension
|  |  |  |  +: class org.eclipse.jetty.websocket.core.internal.IdentityExtension
|  |  |  |  +: class org.eclipse.jetty.websocket.core.internal.ValidationExtension
|  |  |  |  +: class org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension
|  |  |  +~ org.eclipse.jetty.util.DecoratedObjectFactory[decorators=3]
|  |  |  +~ QueuedThreadPool[qtp1495161082]@591e58fa{STARTED,8<=8<=200,i=5,r=-1,q=0}[ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0}] - STARTED
|  |  +- WebSocketServerComponentsCleanupListener
|  |  += JettyWebSocketServerContainer@6869a3b3{STARTED} - STARTED
|  |  |  += JettyServerFrameHandlerFactory@6ab4ba9f{STARTED} - STARTED
|  |  |  |  +> java.util.concurrent.ConcurrentHashMap@0{size=0}
|  |  |  += SessionTracker@27ace0b1{STARTED} - STARTED
|  |  |  |  +> java.util.Collections$SetFromMap@0(size=0)
|  |  |  +> ConfigurationCustomizer@664e5dee{idleTimeout=null, writeTimeout=null, autoFragment=null, maxFrameSize=null, inputBufferSize=null, outputBufferSize=null, maxBinaryMessageSize=null, maxTextMessageSize=null, maxOutgoingFrames=null}
|  |  +- JettyWebSocketServerContainerCleanupListener
|  |  +- org.eclipse.jetty.servlet.listener.ELContextCleaner@431f1eaf
|  |  +- org.eclipse.jetty.servlet.listener.IntrospectorCleaner@cb03411
|  |  +> WebAppClassLoader{254692047}@f2e4acf
|  |  |  +> URLs size=0
|  |  |  +> jdk.internal.loader.ClassLoaders$AppClassLoader@5e2de80c
|  |  +> Systemclasses file:/D:/Projects/verdi_2/target/classes/static@769d513 size=14
|  |  |  +> jakarta.
|  |  |  +> java.
|  |  |  +> javax.
|  |  |  +> org.eclipse.jetty.jndi.
|  |  |  +> org.eclipse.jetty.jsp.
|  |  |  +> org.eclipse.jetty.servlet.DefaultServlet
|  |  |  +> org.eclipse.jetty.servlet.NoJspServlet
|  |  |  +> org.eclipse.jetty.servlet.StatisticsServlet
|  |  |  +> org.eclipse.jetty.websocket.api.
|  |  |  +> org.eclipse.jetty.websocket.client.
|  |  |  +> org.eclipse.jetty.websocket.server.
|  |  |  +> org.eclipse.jetty.websocket.servlet.
|  |  |  +> org.w3c.
|  |  |  +> org.xml.
|  |  +> Serverclasses file:/D:/Projects/verdi_2/target/classes/static@769d513 size=18
|  |  |  +> -org.eclipse.jetty.apache.
|  |  |  +> -org.eclipse.jetty.jndi.
|  |  |  +> -org.eclipse.jetty.jsp.
|  |  |  +> -org.eclipse.jetty.servlet.DefaultServlet
|  |  |  +> -org.eclipse.jetty.servlet.NoJspServlet
|  |  |  +> -org.eclipse.jetty.servlet.StatisticsServlet
|  |  |  +> -org.eclipse.jetty.servlet.listener.
|  |  |  +> -org.eclipse.jetty.websocket.api.
|  |  |  +> -org.eclipse.jetty.websocket.client.
|  |  |  +> -org.eclipse.jetty.websocket.server.
|  |  |  +> -org.eclipse.jetty.websocket.servlet.
|  |  |  +> org.eclipse.jdt.
|  |  |  +> org.eclipse.jetty.
|  |  |  +> org.eclipse.jetty.server.config.
|  |  |  +> org.eclipse.jetty.server.internal.
|  |  |  +> org.eclipse.jetty.websocket.client.config.
|  |  |  +> org.eclipse.jetty.websocket.client.impl.
|  |  |  +> org.objectweb.asm.
|  |  +> Configurations file:/D:/Projects/verdi_2/target/classes/static@769d513 size=13
|  |  |  +> org.eclipse.jetty.webapp.WebInfConfiguration
|  |  |  +> org.eclipse.jetty.webapp.WebXmlConfiguration
|  |  |  +> org.eclipse.jetty.webapp.MetaInfConfiguration
|  |  |  +> org.eclipse.jetty.webapp.FragmentConfiguration
|  |  |  +> org.eclipse.jetty.websocket.server.config.JettyWebSocketConfiguration
|  |  |  +> org.eclipse.jetty.websocket.client.config.JettyWebSocketClientConfiguration
|  |  |  +> org.eclipse.jetty.webapp.JndiConfiguration
|  |  |  +> org.eclipse.jetty.webapp.JspConfiguration
|  |  |  +> org.eclipse.jetty.webapp.WebAppConfiguration
|  |  |  +> org.eclipse.jetty.plus.webapp.EnvConfiguration
|  |  |  +> org.eclipse.jetty.plus.webapp.PlusConfiguration
|  |  |  +> org.eclipse.jetty.annotations.AnnotationConfiguration
|  |  |  +> org.eclipse.jetty.webapp.JettyWebXmlConfiguration
|  |  +> Handler attributes file:/D:/Projects/verdi_2/target/classes/static@769d513 size=5
|  |  |  +> org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern=.*/[^/]*servlet-api-[^/]*\.jar$|.*/javax.servlet.jsp.jstl-.*\.jar$|.*/[^/]*taglibs.*\.jar$
|  |  |  +> org.eclipse.jetty.lifecyleCallbackCollection=org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection@4c59e45e
|  |  |  +> org.eclipse.jetty.server.Executor=QueuedThreadPool[qtp1495161082]@591e58fa{STARTED,8<=8<=200,i=5,r=-1,q=0}[ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0}]
|  |  |  +> org.eclipse.jetty.injectionCollection=org.eclipse.jetty.plus.annotation.InjectionCollection@58ec7116
|  |  |  +> jakarta.servlet.context.tempdir=C:\Users\SV\AppData\Local\Temp\jetty-0_0_0_0-8086-static-_-any-14226370079976394059
|  |  +> Context attributes file:/D:/Projects/verdi_2/target/classes/static@769d513 size=7
|  |  |  +> org.eclipse.jetty.util.DecoratedObjectFactory=org.eclipse.jetty.util.DecoratedObjectFactory[decorators=3]
|  |  |  +> org.eclipse.jetty.websocket.api.WebSocketContainer=JettyWebSocketServerContainer@6869a3b3{STARTED}
|  |  |  +> resourceCache=ResourceCache[null,org.eclipse.jetty.servlet.DefaultServlet@4b7c4456]@1673389762
|  |  |  +> org.apache.tomcat.InstanceManager=org.apache.tomcat.SimpleInstanceManager@713064e8
|  |  |  +> org.eclipse.jetty.websocket.core.WebSocketComponents=WebSocketServerComponents@f3021cb{STARTED}
|  |  |  +> org.eclipse.jetty.websocket.core.server.WebSocketMappings=org.eclipse.jetty.websocket.core.server.WebSocketMappings@4fad6218
|  |  |  +> org.apache.jasper.compiler.TldCache=org.apache.jasper.compiler.TldCache@1bf39d06
|  |  +> EventListeners o.e.j.w.WebAppContext@769d513{/,file:///D:/Projects/verdi_2/target/classes/static/,AVAILABLE}{file:/D:/Projects/verdi_2/target/classes/static} size=5
|  |  |  +> WebSocketServerComponentsCleanupListener
|  |  |  +> JettyWebSocketServerContainer@6869a3b3{STARTED} - STARTED
|  |  |  |  += JettyServerFrameHandlerFactory@6ab4ba9f{STARTED} - STARTED
|  |  |  |  |  +> java.util.concurrent.ConcurrentHashMap@0{size=0}
|  |  |  |  += SessionTracker@27ace0b1{STARTED} - STARTED
|  |  |  |  |  +> java.util.Collections$SetFromMap@0(size=0)
|  |  |  |  +> ConfigurationCustomizer@664e5dee{idleTimeout=null, writeTimeout=null, autoFragment=null, maxFrameSize=null, inputBufferSize=null, outputBufferSize=null, maxBinaryMessageSize=null, maxTextMessageSize=null, maxOutgoingFrames=null}
|  |  |  +> JettyWebSocketServerContainerCleanupListener
|  |  |  +> org.eclipse.jetty.servlet.listener.ELContextCleaner@431f1eaf
|  |  |  +> org.eclipse.jetty.servlet.listener.IntrospectorCleaner@cb03411
|  |  +> Initparams file:/D:/Projects/verdi_2/target/classes/static@769d513 size=1
|  |     +> org.eclipse.jetty.servlet.Default.dirAllowed=false
|  += StatisticsHandler@68217d41{STARTED,r=0,d=0} - STARTED
|     += ServletHandler@387bf2d9{STARTED} - STARTED
|        +> listeners ServletHandler@387bf2d9{STARTED} size=2
|        |  +> org.eclipse.jetty.servlet.listener.ELContextCleaner@74aa9c72{src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml} - STARTED
|        |  +> org.eclipse.jetty.servlet.listener.IntrospectorCleaner@5c20aab9{src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml} - STARTED
|        +> filters ServletHandler@387bf2d9{STARTED} size=0
|        +> filterMappings ServletHandler@387bf2d9{STARTED} size=0
|        +> servlets ServletHandler@387bf2d9{STARTED} size=2
|        |  +> default==org.eclipse.jetty.servlet.DefaultServlet@5c13d641{jsp=null,order=0,inst=true,async=false,src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml,STARTED} - STARTED
|        |  |  +> NotAsync:org.eclipse.jetty.servlet.DefaultServlet@4b7c4456
|        |  |  +> initParams size=9
|        |  |     +> dirAllowed=true
|        |  |     +> maxCacheSize=256000000
|        |  |     +> maxCachedFileSize=200000000
|        |  |     +> welcomeServlets=false
|        |  |     +> useFileMappedBuffer=true
|        |  |     +> acceptRanges=true
|        |  |     +> etags=false
|        |  |     +> maxCachedFiles=2048
|        |  |     +> redirectWelcome=false
|        |  +> jsp==org.eclipse.jetty.jsp.JettyJspServlet@19c47{jsp=null,order=0,inst=true,async=false,src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml,STARTED} - STARTED
|        |     +> NotAsync:org.eclipse.jetty.jsp.JettyJspServlet@2c768ada
|        |     +> initParams size=4
|        |        +> compilerSourceVM=1.8
|        |        +> compilerTargetVM=1.8
|        |        +> scratchdir=C:\Users\SV\AppData\Local\Temp\jetty-0_0_0_0-8086-static-_-any-14226370079976394059\jsp
|        |        +> xpoweredBy=false
|        +> servletMappings ServletHandler@387bf2d9{STARTED} size=2
|        |  +> [/]=>default
|        |  +> [*.jsp, *.jspf, *.jspx, *.xsp, *.JSP, *.JSPF, *.JSPX, *.XSP]=>jsp
|        +> durable ServletHandler@387bf2d9{STARTED} size=4
|           +> default==org.eclipse.jetty.servlet.DefaultServlet@5c13d641{jsp=null,order=0,inst=true,async=false,src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml,STARTED} - STARTED
|           |  +> NotAsync:org.eclipse.jetty.servlet.DefaultServlet@4b7c4456
|           |  +> initParams size=9
|           |     +> dirAllowed=true
|           |     +> maxCacheSize=256000000
|           |     +> maxCachedFileSize=200000000
|           |     +> welcomeServlets=false
|           |     +> useFileMappedBuffer=true
|           |     +> acceptRanges=true
|           |     +> etags=false
|           |     +> maxCachedFiles=2048
|           |     +> redirectWelcome=false
|           +> jsp==org.eclipse.jetty.jsp.JettyJspServlet@19c47{jsp=null,order=0,inst=true,async=false,src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml,STARTED} - STARTED
|           |  +> NotAsync:org.eclipse.jetty.jsp.JettyJspServlet@2c768ada
|           |  +> initParams size=4
|           |     +> compilerSourceVM=1.8
|           |     +> compilerTargetVM=1.8
|           |     +> scratchdir=C:\Users\SV\AppData\Local\Temp\jetty-0_0_0_0-8086-static-_-any-14226370079976394059\jsp
|           |     +> xpoweredBy=false
|           +> org.eclipse.jetty.servlet.listener.ELContextCleaner@74aa9c72{src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml} - STARTED
|           +> org.eclipse.jetty.servlet.listener.IntrospectorCleaner@5c20aab9{src=DESCRIPTOR:jar:file:/C:/Users/SV/.m2/repository/org/eclipse/jetty/jetty-webapp/11.0.11/jetty-webapp-11.0.11.jar!/org/eclipse/jetty/webapp/webdefault.xml} - STARTED
+= ServerConnector@35c09b94{HTTP/1.1, (http/1.1)}{0.0.0.0:8086} - STARTED
|  +~ QueuedThreadPool[qtp1495161082]@591e58fa{STARTED,8<=8<=200,i=5,r=-1,q=0}[ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0}] - STARTED
|  += ScheduledExecutorScheduler@1ac45389{STARTED} - STARTED
|  +- ArrayByteBufferPool@5ae95707{minBufferCapacity=0, maxBufferCapacity=65536, maxQueueLength=-1, factor=1024}
|  |  +> java.util.ArrayList@7498ce09(size=4)
|  |     +: HeapMemory: 0/533200896
|  |     +: DirectMemory: 0/533200896
|  |     +: Indirect Buckets size=0
|  |     +: Direct Buckets size=0
|  +- org.eclipse.jetty.io.ArrayRetainableByteBufferPool@62891fc8{min=0,max=65536,buckets=64,heap=0/533200896,direct=0/533200896}
|  |  +> direct size=64
|  |  |  +> Bucket@367b22e5[inUse=0,size=0,max=2147483647,closed=false]{capacity=1024,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@4c48fe92[inUse=0,size=0,max=2147483647,closed=false]{capacity=2048,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@732c9b5c[inUse=0,size=0,max=2147483647,closed=false]{capacity=3072,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@38320e34[inUse=0,size=0,max=2147483647,closed=false]{capacity=4096,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@3d6a6bee[inUse=0,size=0,max=2147483647,closed=false]{capacity=5120,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@36ddaebf[inUse=0,size=0,max=2147483647,closed=false]{capacity=6144,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@213c3543[inUse=0,size=0,max=2147483647,closed=false]{capacity=7168,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@9d7ccfe[inUse=0,size=0,max=2147483647,closed=false]{capacity=8192,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@670ce331[inUse=0,size=0,max=2147483647,closed=false]{capacity=9216,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@3cff0139[inUse=0,size=0,max=2147483647,closed=false]{capacity=10240,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@7c29adc8[inUse=0,size=0,max=2147483647,closed=false]{capacity=11264,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@4b2e3e8f[inUse=0,size=0,max=2147483647,closed=false]{capacity=12288,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@4bbb49b0[inUse=0,size=0,max=2147483647,closed=false]{capacity=13312,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@f096f37[inUse=0,size=0,max=2147483647,closed=false]{capacity=14336,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@3effd4f3[inUse=0,size=0,max=2147483647,closed=false]{capacity=15360,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@41f4fe5[inUse=0,size=0,max=2147483647,closed=false]{capacity=16384,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@15f8701f[inUse=0,size=0,max=2147483647,closed=false]{capacity=17408,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@514cd540[inUse=0,size=0,max=2147483647,closed=false]{capacity=18432,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@11d4dbd6[inUse=0,size=0,max=2147483647,closed=false]{capacity=19456,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@6f4ade6e[inUse=0,size=0,max=2147483647,closed=false]{capacity=20480,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@39e43310[inUse=0,size=0,max=2147483647,closed=false]{capacity=21504,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@eb507b9[inUse=0,size=0,max=2147483647,closed=false]{capacity=22528,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@390877d2[inUse=0,size=0,max=2147483647,closed=false]{capacity=23552,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@86733[inUse=0,size=0,max=2147483647,closed=false]{capacity=24576,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@186cb891[inUse=0,size=0,max=2147483647,closed=false]{capacity=25600,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@3ec2ecea[inUse=0,size=0,max=2147483647,closed=false]{capacity=26624,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@440eaa07[inUse=0,size=0,max=2147483647,closed=false]{capacity=27648,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@7fc7c4a[inUse=0,size=0,max=2147483647,closed=false]{capacity=28672,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@7aa9e414[inUse=0,size=0,max=2147483647,closed=false]{capacity=29696,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@53a5e217[inUse=0,size=0,max=2147483647,closed=false]{capacity=30720,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@624a24f6[inUse=0,size=0,max=2147483647,closed=false]{capacity=31744,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@6b00ad9[inUse=0,size=0,max=2147483647,closed=false]{capacity=32768,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@338cc75f[inUse=0,size=0,max=2147483647,closed=false]{capacity=33792,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@4f453e63[inUse=0,size=0,max=2147483647,closed=false]{capacity=34816,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@7c9bdee9[inUse=0,size=0,max=2147483647,closed=false]{capacity=35840,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@7afbf561[inUse=0,size=0,max=2147483647,closed=false]{capacity=36864,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@2f98635e[inUse=0,size=0,max=2147483647,closed=false]{capacity=37888,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@49c8f6e8[inUse=0,size=0,max=2147483647,closed=false]{capacity=38912,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@6b0615ae[inUse=0,size=0,max=2147483647,closed=false]{capacity=39936,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@4e73b552[inUse=0,size=0,max=2147483647,closed=false]{capacity=40960,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@221dad51[inUse=0,size=0,max=2147483647,closed=false]{capacity=41984,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@2cec704c[inUse=0,size=0,max=2147483647,closed=false]{capacity=43008,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@771cbb1a[inUse=0,size=0,max=2147483647,closed=false]{capacity=44032,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@2416498e[inUse=0,size=0,max=2147483647,closed=false]{capacity=45056,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@6b2e0f78[inUse=0,size=0,max=2147483647,closed=false]{capacity=46080,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@240f6c41[inUse=0,size=0,max=2147483647,closed=false]{capacity=47104,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@3659d7b1[inUse=0,size=0,max=2147483647,closed=false]{capacity=48128,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@2015b2cd[inUse=0,size=0,max=2147483647,closed=false]{capacity=49152,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@3bdb2c78[inUse=0,size=0,max=2147483647,closed=false]{capacity=50176,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@64693226[inUse=0,size=0,max=2147483647,closed=false]{capacity=51200,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@1c758545[inUse=0,size=0,max=2147483647,closed=false]{capacity=52224,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@117bcfdc[inUse=0,size=0,max=2147483647,closed=false]{capacity=53248,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@73a19967[inUse=0,size=0,max=2147483647,closed=false]{capacity=54272,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@5e746d37[inUse=0,size=0,max=2147483647,closed=false]{capacity=55296,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@6e1b9411[inUse=0,size=0,max=2147483647,closed=false]{capacity=56320,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@21d1b321[inUse=0,size=0,max=2147483647,closed=false]{capacity=57344,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@5ec46cdd[inUse=0,size=0,max=2147483647,closed=false]{capacity=58368,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@2324bfe7[inUse=0,size=0,max=2147483647,closed=false]{capacity=59392,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@112d1c8e[inUse=0,size=0,max=2147483647,closed=false]{capacity=60416,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@3d49fd31[inUse=0,size=0,max=2147483647,closed=false]{capacity=61440,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@4016ccc1[inUse=0,size=0,max=2147483647,closed=false]{capacity=62464,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@46cb98a3[inUse=0,size=0,max=2147483647,closed=false]{capacity=63488,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@3ffb3598[inUse=0,size=0,max=2147483647,closed=false]{capacity=64512,inuse=0(0%)}
|  |  |  |  +> entries size=0
|  |  |  +> Bucket@4da9f723[inUse=0,size=0,max=2147483647,closed=false]{capacity=65536,inuse=0(0%)}
|  |  |     +> entries size=0
|  |  +> indirect size=64
|  |     +> Bucket@3b2f4a93[inUse=0,size=0,max=2147483647,closed=false]{capacity=1024,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@213bd3d5[inUse=0,size=0,max=2147483647,closed=false]{capacity=2048,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@470a659f[inUse=0,size=0,max=2147483647,closed=false]{capacity=3072,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@451882b2[inUse=0,size=0,max=2147483647,closed=false]{capacity=4096,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@4a23350[inUse=0,size=0,max=2147483647,closed=false]{capacity=5120,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@7b78ed6a[inUse=0,size=0,max=2147483647,closed=false]{capacity=6144,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@6fca5907[inUse=0,size=0,max=2147483647,closed=false]{capacity=7168,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@6ec65b5e[inUse=0,size=0,max=2147483647,closed=false]{capacity=8192,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@7bebcd65[inUse=0,size=0,max=2147483647,closed=false]{capacity=9216,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@47447ccf[inUse=0,size=0,max=2147483647,closed=false]{capacity=10240,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@7afb1741[inUse=0,size=0,max=2147483647,closed=false]{capacity=11264,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@263bbfeb[inUse=0,size=0,max=2147483647,closed=false]{capacity=12288,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@31edeac[inUse=0,size=0,max=2147483647,closed=false]{capacity=13312,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@67d86804[inUse=0,size=0,max=2147483647,closed=false]{capacity=14336,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@45bb2aa1[inUse=0,size=0,max=2147483647,closed=false]{capacity=15360,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@3e84111a[inUse=0,size=0,max=2147483647,closed=false]{capacity=16384,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@4b1a43d8[inUse=0,size=0,max=2147483647,closed=false]{capacity=17408,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@6fa69af7[inUse=0,size=0,max=2147483647,closed=false]{capacity=18432,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@73545b80[inUse=0,size=0,max=2147483647,closed=false]{capacity=19456,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@6d469831[inUse=0,size=0,max=2147483647,closed=false]{capacity=20480,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@74db12c2[inUse=0,size=0,max=2147483647,closed=false]{capacity=21504,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@2ff15f8c[inUse=0,size=0,max=2147483647,closed=false]{capacity=22528,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@7ea899a9[inUse=0,size=0,max=2147483647,closed=false]{capacity=23552,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@2776015d[inUse=0,size=0,max=2147483647,closed=false]{capacity=24576,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@b174a73[inUse=0,size=0,max=2147483647,closed=false]{capacity=25600,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@2e3f79a2[inUse=0,size=0,max=2147483647,closed=false]{capacity=26624,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@1460c81d[inUse=0,size=0,max=2147483647,closed=false]{capacity=27648,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@38b5f25[inUse=0,size=0,max=2147483647,closed=false]{capacity=28672,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@327ed9f5[inUse=0,size=0,max=2147483647,closed=false]{capacity=29696,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@67594471[inUse=0,size=0,max=2147483647,closed=false]{capacity=30720,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@756b58a7[inUse=0,size=0,max=2147483647,closed=false]{capacity=31744,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@2cc04358[inUse=0,size=0,max=2147483647,closed=false]{capacity=32768,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@68b58644[inUse=0,size=0,max=2147483647,closed=false]{capacity=33792,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@45e22def[inUse=0,size=0,max=2147483647,closed=false]{capacity=34816,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@6ae3fb94[inUse=0,size=0,max=2147483647,closed=false]{capacity=35840,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@4417af13[inUse=0,size=0,max=2147483647,closed=false]{capacity=36864,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@d48673[inUse=0,size=0,max=2147483647,closed=false]{capacity=37888,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@548d5ed3[inUse=0,size=0,max=2147483647,closed=false]{capacity=38912,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@21c7208d[inUse=0,size=0,max=2147483647,closed=false]{capacity=39936,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@58516c91[inUse=0,size=0,max=2147483647,closed=false]{capacity=40960,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@7c129ef6[inUse=0,size=0,max=2147483647,closed=false]{capacity=41984,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@42d73c61[inUse=0,size=0,max=2147483647,closed=false]{capacity=43008,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@5a8cbffe[inUse=0,size=0,max=2147483647,closed=false]{capacity=44032,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@96a75da[inUse=0,size=0,max=2147483647,closed=false]{capacity=45056,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@61e7bf2f[inUse=0,size=0,max=2147483647,closed=false]{capacity=46080,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@1a28b346[inUse=0,size=0,max=2147483647,closed=false]{capacity=47104,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@25e49cb2[inUse=0,size=0,max=2147483647,closed=false]{capacity=48128,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@7f7af971[inUse=0,size=0,max=2147483647,closed=false]{capacity=49152,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@23382f76[inUse=0,size=0,max=2147483647,closed=false]{capacity=50176,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@7c551ad4[inUse=0,size=0,max=2147483647,closed=false]{capacity=51200,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@7d5508e0[inUse=0,size=0,max=2147483647,closed=false]{capacity=52224,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@554cd74a[inUse=0,size=0,max=2147483647,closed=false]{capacity=53248,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@37ed010a[inUse=0,size=0,max=2147483647,closed=false]{capacity=54272,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@633a2e99[inUse=0,size=0,max=2147483647,closed=false]{capacity=55296,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@367d2816[inUse=0,size=0,max=2147483647,closed=false]{capacity=56320,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@5b84f14[inUse=0,size=0,max=2147483647,closed=false]{capacity=57344,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@5a82ebf8[inUse=0,size=0,max=2147483647,closed=false]{capacity=58368,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@68fe48d7[inUse=0,size=0,max=2147483647,closed=false]{capacity=59392,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@379ce046[inUse=0,size=0,max=2147483647,closed=false]{capacity=60416,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@701bc94e[inUse=0,size=0,max=2147483647,closed=false]{capacity=61440,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@3d8b319e[inUse=0,size=0,max=2147483647,closed=false]{capacity=62464,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@27a97e08[inUse=0,size=0,max=2147483647,closed=false]{capacity=63488,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@77e7246b[inUse=0,size=0,max=2147483647,closed=false]{capacity=64512,inuse=0(0%)}
|  |     |  +> entries size=0
|  |     +> Bucket@5918c260[inUse=0,size=0,max=2147483647,closed=false]{capacity=65536,inuse=0(0%)}
|  |        +> entries size=0
|  +- org.eclipse.jetty.server.AbstractConnector$1@3d7b1f1c
|  += HttpConnectionFactory@2d0bfb24[HTTP/1.1] - STARTED
|  |  +- HttpConfiguration@7eb6b6b6{32768/8192,8192/8192,https://:0,[]}
|  |     +> customizers size=0
|  |     +> formEncodedMethods size=2
|  |     |  +> POST
|  |     |  +> PUT
|  |     +> outputBufferSize=32768
|  |     +> outputAggregationSize=8192
|  |     +> requestHeaderSize=8192
|  |     +> responseHeaderSize=8192
|  |     +> headerCacheSize=1024
|  |     +> secureScheme=https
|  |     +> securePort=0
|  |     +> idleTimeout=-1
|  |     +> sendDateHeader=true
|  |     +> sendServerVersion=false
|  |     +> sendXPoweredBy=false
|  |     +> delayDispatchUntilContent=true
|  |     +> persistentConnectionsEnabled=true
|  |     +> maxErrorDispatches=10
|  |     +> minRequestDataRate=0
|  |     +> minResponseDataRate=0
|  |     +> requestCookieCompliance=org.eclipse.jetty.http.CookieCompliance@4726927c
|  |     +> responseCookieCompliance=org.eclipse.jetty.http.CookieCompliance@4726927c
|  |     +> notifyRemoteAsyncErrors=true
|  |     +> relativeRedirectAllowed=false
|  += SelectorManager@ServerConnector@35c09b94{HTTP/1.1, (http/1.1)}{0.0.0.0:8086} - STARTED
|  |  += ManagedSelector@10ef5fa0{STARTED} id=0 keys=0 selected=0 updates=0 - STARTED
|  |  |  += AdaptiveExecutionStrategy@244e619a/SelectorProducer@10acd6/PRODUCING/p=false/QueuedThreadPool[qtp1495161082]@591e58fa{STARTED,8<=8<=200,i=5,r=-1,q=0}[ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0}][pc=0,pic=0,pec=0,epc=0]@2022-09-07T15:46:19.3457589+02:00 - STARTED
|  |  |  |  +- SelectorProducer@10acd6
|  |  |  |  +~ QueuedThreadPool[qtp1495161082]@591e58fa{STARTED,8<=8<=200,i=5,r=-1,q=0}[ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0}] - STARTED
|  |  |  +> updates @ 2022-09-07T15:46:19.3290978+02:00 size=0
|  |  |  +> keys @ 2022-09-07T15:46:19.3452529+02:00 size=0
|  |  += ManagedSelector@61dde151{STARTED} id=1 keys=0 selected=0 updates=0 - STARTED
|  |     += AdaptiveExecutionStrategy@b25b095/SelectorProducer@5cb042da/PRODUCING/p=false/QueuedThreadPool[qtp1495161082]@591e58fa{STARTED,8<=8<=200,i=5,r=-1,q=0}[ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0}][pc=0,pic=0,pec=0,epc=0]@2022-09-07T15:46:19.346254+02:00 - STARTED
|  |     |  +- SelectorProducer@5cb042da
|  |     |  +~ QueuedThreadPool[qtp1495161082]@591e58fa{STARTED,8<=8<=200,i=5,r=-1,q=0}[ReservedThreadExecutor@39008c9f{reserved=0/4,pending=0}] - STARTED
|  |     +> updates @ 2022-09-07T15:46:19.3459617+02:00 size=0
|  |     +> keys @ 2022-09-07T15:46:19.3461094+02:00 size=0
|  +- sun.nio.ch.ServerSocketChannelImpl[/[0:0:0:0:0:0:0:0]:8086]
|  +- qtp1495161082-29-acceptor-0@5c76950b-ServerConnector@35c09b94{HTTP/1.1, (http/1.1)}{0.0.0.0:8086}
+= ErrorHandler@59c33386{STARTED} - STARTED
+= DefaultSessionIdManager@396e6d9{STARTED}[worker=node0] - STARTED
|  += HouseKeeper@78411116{STARTED}[interval=600000, ownscheduler=true] - STARTED
+= InflaterPool@4aaae508{STARTED,size=0,capacity=200} - STARTED
|  +- Pool@3fc05ea2[inUse=0,size=0,max=200,closed=false]
|     +> entries size=0
+= DeflaterPool@6009bea{STARTED,size=0,capacity=200} - STARTED
|  +- Pool@7c891ba7[inUse=0,size=0,max=200,closed=false]
|     +> entries size=0
+> jdk.internal.loader.ClassLoaders$AppClassLoader@5e2de80c
   +> packages size=197
   |  +> package org.mariadb.jdbc.internal.util.constant
   |  +> package org.apache.logging.log4j.core.config.plugins.validation.validators, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.juli.logging, version 2.3
   |  +> package org.apache.logging.log4j.core.config.properties, Apache Log4j Core, version 2.17.1
   |  +> package org.eclipse.jetty.apache.jsp
   |  +> package org.slf4j.spi
   |  +> package org.eclipse.jetty.jsp
   |  +> package org.eclipse.jetty.plus.jndi
   |  +> package org.apache.commons.logging.impl, Apache Commons Logging, version 1.2
   |  +> package verishare.api.incoming.dashboard
   |  +> package org.postgresql.util
   |  +> package org.apache.logging.log4j.core.config.arbiters, Apache Log4j Core, version 2.17.1
   |  +> package org.mariadb.jdbc.internal.com.read.dao
   |  +> package jakarta.servlet.http
   |  +> package org.apache.logging.log4j.core.filter, Apache Log4j Core, version 2.17.1
   |  +> package verishare.api
   |  +> package org.apache.jasper.servlet, version 2.3
   |  +> package microsoft.sql
   |  +> package org.eclipse.jetty.server
   |  +> package org.apache.logging.log4j.core.layout, Apache Log4j Core, version 2.17.1
   |  +> package org.eclipse.jetty.util.component
   |  +> package com.google.gson.internal
   |  +> package org.eclipse.jetty.xml
   |  +> package org.eclipse.jetty.jndi.local
   |  +> package org.apache.logging.log4j, Apache Log4j API, version 2.17.1
   |  +> package org.apache.commons.logging, Apache Commons Logging, version 1.2
   |  +> package org.apache.logging.log4j.core.appender.rolling.action, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.message, Apache Log4j API, version 2.17.1
   |  +> package org.slf4j.event
   |  +> package javassist.bytecode, Javassist, version 3.19.0-GA
   |  +> package org.apache.tomcat.util.compat, version 2.3
   |  +> package org.apache.commons.pool2.impl, Apache Commons Pool, version 2.6.0
   |  +> package org.springframework.web.client
   |  +> package org.apache.logging.log4j.core.appender.rewrite, Apache Log4j Core, version 2.17.1
   |  +> package org.mariadb.jdbc.internal.com.read.resultset
   |  +> package com.google.common.base
   |  +> package org.apache.jasper.compiler.tagplugin, version 2.3
   |  +> package org.eclipse.jetty.util.thread.strategy
   |  +> package org.eclipse.jetty.websocket.server
   |  +> package org.mariadb.jdbc.internal.util.exceptions
   |  +> package org.eclipse.jetty.webapp
   |  +> package jakarta.servlet
   |  +> package org.eclipse.jetty.util.compression
   |  +> package org.apache.logging.log4j.core.appender.mom.kafka, Apache Log4j Core, version 2.17.1
   |  +> package com.jcraft.jsch
   |  +> package org.apache.logging.log4j.status, Apache Log4j API, version 2.17.1
   |  +> package org.apache.logging.log4j.core.config.yaml, Apache Log4j Core, version 2.17.1
   |  +> package org.slf4j
   |  +> package org.apache.logging.log4j.core.config, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.core.selector, Apache Log4j Core, version 2.17.1
   |  +> package com.fasterxml.jackson.core, Jackson-core, version 2.11.3
   |  +> package org.eclipse.jetty.websocket.api.exceptions
   |  +> package verishare.api.missedcalls
   |  +> package org.eclipse.jetty.jndi
   |  +> package org.eclipse.jetty.plus.webapp
   |  +> package org.mariadb.jdbc.internal.com.send
   |  +> package org.eclipse.jetty.websocket.core.exception
   |  +> package org.eclipse.jetty.annotations
   |  +> package org.apache.tomcat.util.res, version 2.3
   |  +> package org.springframework.util
   |  +> package org.eclipse.jetty.util.resource
   |  +> package org.apache.logging.log4j.core.config.plugins.util, Apache Log4j Core, version 2.17.1
   |  +> package org.eclipse.jetty.servlet
   |  +> package verishare.db
   |  +> package mssql.googlecode.concurrentlinkedhashmap
   |  +> package org.mariadb.jdbc.internal.util.scheduler
   |  +> package org.eclipse.jetty.server.session
   |  +> package org.apache.commons.pool2, Apache Commons Pool, version 2.6.0
   |  +> package org.apache.logging.log4j.core.lookup, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.core.config.plugins.validation.constraints, Apache Log4j Core, version 2.17.1
   |  +> package org.eclipse.jetty.websocket.core.internal
   |  +> package org.objectweb.asm
   |  +> package org.apache.logging.log4j.core.util.datetime, Apache Log4j Core, version 2.17.1
   |  +> package org.mariadb.jdbc.internal.io.output
   |  +> package javax.ws.rs, version 2.0
   |  +> package org.apache.logging.log4j.core.appender.rolling, Apache Log4j Core, version 2.17.1
   |  +> package org.reflections.serializers
   |  +> package org.eclipse.jetty.websocket.server.config
   |  +> package verishare.api.vmallocation
   |  +> package org.mariadb.jdbc.internal.io.input
   |  +> package verishare.tcn.api
   |  +> package org.slf4j.helpers
   |  +> package org.apache.tomcat.util.digester, version 2.3
   |  +> package com.fasterxml.jackson.databind, jackson-databind, version 2.11.3
   |  +> package org.slf4j.impl
   |  +> package org.mariadb.jdbc.internal.com.read
   |  +> package org.eclipse.jetty.util.security
   |  +> package org.apache.logging.log4j.core.config.plugins.convert, Apache Log4j Core, version 2.17.1
   |  +> package com.google.common.primitives
   |  +> package org.apache.http.client, HttpComponents Apache HttpClient, version 4.5.1
   |  +> package org.apache.logging.log4j.core.config.plugins.visitors, Apache Log4j Core, version 2.17.1
   |  +> package org.eclipse.jetty.jndi.java
   |  +> package org.apache.logging.log4j.core.appender.nosql, Apache Log4j Core, version 2.17.1
   |  +> package org.mariadb.jdbc.internal.com.send.parameters
   |  +> package com.google.gson.reflect
   |  +> package org.apache.logging.log4j.core.appender.db.jdbc, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.core, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.internal, Apache Log4j API, version 2.17.1
   |  +> package org.apache.logging.log4j.core.appender, Apache Log4j Core, version 2.17.1
   |  +> package org.postgresql
   |  +> package org.apache.jasper, version 2.3
   |  +> package org.apache.logging.log4j.core.net, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.core.appender.mom, Apache Log4j Core, version 2.17.1
   |  +> package org.mariadb.jdbc.internal.util
   |  +> package org.mariadb.jdbc.internal.failover
   |  +> package com.google.gson.stream
   |  +> package verishare.webServer
   |  +> package org.apache.logging.log4j.core.appender.mom.jeromq, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.core.net.ssl, Apache Log4j Core, version 2.17.1
   |  +> package jakarta.servlet.annotation
   |  +> package org.apache.commons.dbcp2, Apache Commons DBCP, version 2.5.0
   |  +> package org.apache.logging.log4j.core.config.status, Apache Log4j Core, version 2.17.1
   |  +> package org.eclipse.jetty.security.authentication
   |  +> package org.springframework.core
   |  +> package org.apache.tomcat.util.security, version 2.3
   |  +> package org.apache.tomcat.util.descriptor, version 2.3
   |  +> package org.eclipse.jetty.websocket.core.server.internal
   |  +> package org.apache.tomcat, version 2.3
   |  +> package org.mariadb.jdbc.util
   |  +> package org.eclipse.jetty.websocket.core.server
   |  +> package org.apache.logging.log4j.core.impl, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.core.config.json, Apache Log4j Core, version 2.17.1
   |  +> package org.eclipse.jetty.http
   |  +> package verishare.verdial_db
   |  +> package org.eclipse.jetty.websocket.client.config
   |  +> package org.mariadb.jdbc.credential
   |  +> package org.eclipse.jetty.util.thread
   |  +> package org.eclipse.jetty.util.statistic
   |  +> package org.apache.tomcat.util.scan, version 2.3
   |  +> package org.eclipse.jetty.websocket.common
   |  +> package org.apache.logging.log4j.util, Apache Log4j API, version 2.17.1
   |  +> package org.apache.logging.log4j.core.util, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.jasper.security, version 2.3
   |  +> package org.apache.logging.log4j.core.script, Apache Log4j Core, version 2.17.1
   |  +> package org.eclipse.jetty.server.handler
   |  +> package org.eclipse.jetty.server.handler.gzip
   |  +> package org.reflections
   |  +> package jakarta.servlet.jsp, version 2.3
   |  +> package org.mariadb.jdbc.internal.util.pid
   |  +> package verishare.log4J2.utils
   |  +> package org.apache.logging.log4j.core.jmx, Apache Log4j Core, version 2.17.1
   |  +> package org.mariadb.jdbc.internal.util.dao
   |  +> package org.eclipse.jetty.plus.annotation
   |  +> package org.mariadb.jdbc
   |  +> package com.google.gson
   |  +> package verishare.api.intercom
   |  +> package org.postgresql.core
   |  +> package org.mariadb.jdbc.authentication
   |  +> package org.eclipse.jetty.websocket.core.internal.util
   |  +> package org.reflections.util
   |  +> package jakarta.annotation.security, version 2.1
   |  +> package org.eclipse.jetty.websocket.core
   |  +> package org.apache.jasper.runtime, version 2.3
   |  +> package org.apache.logging.log4j.core.config.plugins.validation, Apache Log4j Core, version 2.17.1
   |  +> package org.mariadb.jdbc.internal
   |  +> package org.eclipse.jetty.security
   |  +> package jakarta.annotation, version 2.1
   |  +> package org.eclipse.jetty.io
   |  +> package org.mariadb.jdbc.internal.io.socket
   |  +> package com.google.gson.internal.bind
   |  +> package org.apache.http.client.methods, HttpComponents Apache HttpClient, version 4.5.1
   |  +> package org.apache.logging.log4j.core.time, Apache Log4j Core, version 2.17.1
   |  +> package jakarta.servlet.jsp.tagext, version 2.3
   |  +> package com.google.common.collect
   |  +> package javassist, Javassist, version 3.19.0-GA
   |  +> package org.apache.jasper.compiler, version 2.3
   |  +> package org.apache.logging.log4j.core.async, Apache Log4j Core, version 2.17.1
   |  +> package org.eclipse.jetty.websocket.server.internal
   |  +> package org.apache.logging.log4j.core.appender.db, Apache Log4j Core, version 2.17.1
   |  +> package com.microsoft.sqlserver.jdbc
   |  +> package org.mariadb.jdbc.internal.com.read.resultset.rowprotocol
   |  +> package javassist.bytecode.annotation, Javassist, version 3.19.0-GA
   |  +> package org.apache.logging.log4j.spi, Apache Log4j API, version 2.17.1
   |  +> package org.mariadb.jdbc.internal.logging
   |  +> package org.apache.logging.log4j.core.appender.routing, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.core.config.builder.api, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.util.internal, Apache Log4j API, version 2.17.1
   |  +> package org.eclipse.jetty.http.pathmap
   |  +> package org.reflections.vfs
   |  +> package org.eclipse.jetty.util
   |  +> package org.apache.tomcat.util.descriptor.tld, version 2.3
   |  +> package verishare.api.verinet.selfserve.ivr
   |  +> package org.eclipse.jetty.servlet.listener
   |  +> package org.apache.logging.log4j.core.config.plugins.processor, Apache Log4j Core, version 2.17.1
   |  +> package verishare.api.call_classification
   |  +> package org.reflections.scanners
   |  +> package org.reflections.adapters
   |  +> package org.apache.logging.log4j.core.pattern, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.core.config.xml, Apache Log4j Core, version 2.17.1
2022-09-07 15:46:19.359 INFO  WebHost - sl0ok4t12gki - Jetty Server started! 
   |  +> package jakarta.servlet.descriptor
   |  +> package verishare
   |  +> package org.eclipse.jetty.websocket.api
   |  +> package org.apache.http, HttpComponents Apache HttpCore, version 4.4.3
   |  +> package org.mariadb.jdbc.internal.protocol
   |  +> package org.apache.tomcat.util, version 2.3
   |  +> package org.apache.logging.log4j.core.config.plugins, Apache Log4j Core, version 2.17.1
   |  +> package org.apache.logging.log4j.simple, Apache Log4j API, version 2.17.1
   +> jdk.internal.loader.ClassLoaders$PlatformClassLoader@4b5a5ed1
      +> packages size=17
         +> package java.sql
         +> package sun.security.ec
         +> package com.sun.security.sasl.gsskerb
         +> package sun.security.jgss
         +> package org.jcp.xml.dsig.internal.dom
         +> package sun.util.resources.cldr.provider
         +> package javax.sql
         +> package sun.security.smartcardio
         +> package sun.security.mscapi
         +> package javax.script
         +> package javax.sql.rowset.serial
         +> package sun.security.ec.point
         +> package sun.security.ec.ed
         +> package sun.security.pkcs11.wrapper
         +> package com.sun.jndi.dns
         +> package org.ietf.jgss
         +> package sun.security.pkcs11
key: +- bean, += managed, +~ unmanaged, +? auto, +: iterable, +] array, +@ map, +> undefined
Java Runtime : Java(TM) SE Runtime Environment 17.0.4.1+1-LTS-2

Kind regards Joakim and thanks.

Stefan

StefanViljoen commented 2 years ago

@lorban

I've created a project over here: https://github.com/lorban/jetty-fatjar-static-resource-serving

Simply building it with mvn clean package then starting it with java -jar target/reproducer-8549-1.0-SNAPSHOT-jar-with-dependencies.jar will make Jetty listen on port 8080 and serve the static files that are in the jar's /static folder.

How do I do that?

(I will go read up and try to figure out how to do that, never used GitHub before.)

However, what I did do is to replace my Jetty startup method with the one you give here, and the behaviour is 100% the same as before: it ONLY works inside the IDE. Compile it into a JAR, and it does not work at all when run in JDK 17 outside the NetBeans 14 IDE. Still 404 when running outside the Netbeans 14 IDE from inside the JAR.

E. g. the exact same problem I have been having all along which prompted the initial ticket post here.

I suppose it will be somehow different when correctly downloaded, mvn built, and ran?

Thx

Regards

Stefan

StefanViljoen commented 2 years ago

I've created a project over here: https://github.com/lorban/jetty-fatjar-static-resource-serving

Simply building it with mvn clean package then starting it with java -jar target/reproducer-8549-1.0-SNAPSHOT-jar-with-dependencies.jar will make Jetty listen on port 8080 and serve the static files that are in the jar's /static folder.

Ok figured out how to clone the project down and followed your directions.

It does work as you say... I copied my "static" folder into it, built the JAR with dependencies, copied it to my Linux testing server and ran it there under the official Oracle JDK 17 - and then it CAN serve my HTML etc. correctly out of the same JAR Jetty 11 is running out of.

Thanks! This is some hope.

lorban commented 2 years ago

As @joakime pointed out at https://github.com/lorban/jetty-fatjar-static-resource-serving/commit/2340476d03a832d6764cb12f7295bc3dee1ec0dd#r83302224 this project of mine using the assembly plugin with jar-with-dependencies to create a fat jar only works by chance, and should build the fat jar with the shade plugin instead.

You can try it out by replacing the assembly plugin with the shade plugin that is currently commented out to see that also generates a fat jar albeit with a different name, but in a correct way.

Hopefully that should put you on the right tracks.

StefanViljoen commented 2 years ago

@joakime I've now implemented the Jetty uber jar Maven POM you linked to, e. g.

https://github.com/jetty-project/embedded-jetty-uber-jar/blob/jetty-11.0.x/pom.xml#L160-L236

My project now uses much the same POM, and as far as I can tell from the console output, it is now using the shade plugin, plus it is applying the various exclude tags you list there in that POM example to get rid of META-INF directories, etc.

Obviously I still have my non-Jetty resources listed in my POM (for MSSQL, MySQL, Gson, etc.) and I've commented out the Javadoc and com.mycila plugins for now that are present in your example for licensing and Java doc (which I don't need at the moment).

I also just replaced your example Main class with my project's Main class in the POM example code you show at the link above.

It does now compile, I'm now busy working through

https://github.com/eclipse/jetty.project/blob/jetty-11.0.x/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java#L270

as kindly advised of by @lorban to start up Jetty correctly so it can find the /static folder containing my static web resources in the "right" way.

It still works in the IDE, e. g. all the JSPs and HTML content is accessible, in the "shaded" JAR I now have.

What does this at the bottom of that POM do:

 <repositories>
    <repository>
      <id>jetty-staging</id>
      <url>https://oss.sonatype.org/content/groups/jetty-with-staging</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>

Do I need to add this to mine as well? It does compile and does currently run inside the Netbeans 14 IDE and all the JSP and HTML content, as well as all the Servlets (APIs) is there and working with it running inside the Netbeans 14 IDE.

StefanViljoen commented 2 years ago

@joakime I have now implemented the replacement of the WebAppContext with the Servlet as you demonstrate at

https://github.com/jetty-project/embedded-jetty-cookbook/blob/jetty-11.0.x/src/main/java/org/eclipse/jetty/cookbook/DefaultServletFileServer.java

after switching to Maven shade as you suggested and using the advised POM.xml as I describe in my above post.

In the NetBeans 14 IDE, (as you hinted at earlier) all my JSPs now load in the browser, but none of them actually work. The header tags in the .jsp files, e. g.

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

display in-browser (e. g. they are no longer parsed by anything) and all JSP functionality obviously is dead in all pages.

You mentioned that JSPs need to be modified for Jetty 11 - I now need to make those modifications to get my JSPs working again in (at least) NetBeans 14 - before I once again try to get them to work in a detached JRE outside the Netbeans 14 IDE.

What are the modifications or new tags needed to make JSP files work that are now being rendered by an instance of the ServletContextHandler class vs. as in the past an instance of a WebAppContext class in Jetty 11.0.11?

You also mentioned

ContainerIncludeJarPattern

will need to be changed or removed for Jetty 11.0.11?

Here's my code to start jetty re the above:

public boolean startJettyb(Server server) throws Exception, InterruptedException {
        boolean retVal = false;

        try {
            localLogger.info((String) logEntryRefNumLocal.get() + "Starting Jetty on port " + AppSettings.getJettyServerPort() + ".");

            server = new Server(AppSettings.getJettyServerPort());

            jettyServer = server;

            server.setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize", -1);

            //String webDir = this.getClass().getClassLoader().getResource("static").toExternalForm();                      
            //WebAppContext waContext = new WebAppContext(webDir, "/");            
            ServerConnector connector = new ServerConnector(server);
            server.addConnector(connector);

            ClassLoader cl = WebHost.class.getClassLoader();

            URL f = cl.getResource("static/index.html");

            if (f == null) {
                throw new RuntimeException("Unable to find resource directory");
            }

            URI webRootUri = f.toURI().resolve("./").normalize();

            localLogger.info((String) logEntryRefNumLocal.get() + "Web Root URI:" + webRootUri);

            ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
            context.setContextPath("/");
            context.setBaseResource(Resource.newResource(webRootUri));

            context.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");

            SecurityHandler basicSecurity = getBasicAuthHandler("abc", "def");
            context.setSecurityHandler(basicSecurity);

            context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");

            ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
            holderPwd.setInitParameter("dirAllowed", "true");
            context.addServlet(holderPwd, "/");

            ServletContextHandler provisionContext = new ServletContextHandler();
            provisionContext.setContextPath("/conf");
            provisionContext.addServlet(new ServletHolder(new WebPhoneConfigurator()), "/*");

            ServletContextHandler servletContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
            servletContext.setMaxFormKeys(1000000000);
            servletContext.setContextPath("/api");
            servletContext.addServlet(new ServletHolder(new WebApiServlet()), "/*");

            String cn = "";

            Reflections rf = new Reflections("verishare");
            Set<Class<?>> classWithPath = rf.getTypesAnnotatedWith(javax.ws.rs.Path.class);
            for (Class c : classWithPath) {
                if (cn.length() > 0) {
                    cn += ";";
                }
                cn += c.getCanonicalName();

                localLogger.info((String) logEntryRefNumLocal.get() + "Adding class: " + c.getCanonicalName());
            }

            File tmpFile = new File("tmpdata");
            if (!tmpFile.exists()) {

                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder not found - creating...");

                tmpFile.mkdir();

                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder created.");
            } else {
                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder found - deleting existing files inside it...");

                for (File file : tmpFile.listFiles()) {
                    file.delete();
                }

                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder cleared of contents.");
            }

            localLogger.info((String) logEntryRefNumLocal.get() + "Setting temp file context and instantiating temp file servlet...");

            ServletContextHandler tempFileContext = new ServletContextHandler();
            tempFileContext.setContextPath("/tmpdata");
            tempFileContext.addServlet(new ServletHolder(new TempFileServlet()), "/*");

            localLogger.info((String) logEntryRefNumLocal.get() + "Temp file context set and temp file servlet instantiated.");

            localLogger.info((String) logEntryRefNumLocal.get() + "Setting Jetty handlers for all instantiated Jetty contexts...");

            StatisticsHandler statsHandler = new StatisticsHandler();
            statsHandler.setHandler(context.getServletHandler());

            HandlerList handlers = new HandlerList();
            handlers.setHandlers(new Handler[]{servletContext, provisionContext, tempFileContext, context, statsHandler});

            server.setHandler(handlers);

            //Turn off server identification
            HttpConfiguration httpConfig = new HttpConfiguration();
            httpConfig.setSendServerVersion(false);
            HttpConnectionFactory httpFactory = new HttpConnectionFactory(httpConfig);
            ServerConnector httpConnector = new ServerConnector(server, httpFactory);
            httpConnector.setPort(AppSettings.getJettyServerPort());
            server.setConnectors(new Connector[]{httpConnector});

            server.setStopAtShutdown(true);
            server.setStopTimeout(0x2710L);

            server.start();

            localLogger.info((String) logEntryRefNumLocal.get() + "Jetty Server started!");

            retVal = true;
        } catch (InterruptedException iex) {
            localLogger.error((String) logEntryRefNumLocal.get() + "InterrupedException in WebHost.java startJetty method.", iex);

            retVal = false; //Belt and suspenders

            throw iex;
        } catch (RuntimeException rex) {
            localLogger.error((String) logEntryRefNumLocal.get() + "Runtime  exception in WebHost.java startJetty method.", rex);

            retVal = false;

            throw rex;
        } catch (Exception ex) {
            localLogger.error((String) logEntryRefNumLocal.get() + "General exception in WebHost.java startJetty method.", ex);

            retVal = false;

            throw ex;
        }

        return retVal;
    }
StefanViljoen commented 2 years ago

Investigated this a bit myself, and modified my startup code according to this link:

https://stackoverflow.com/questions/65637135/how-to-enable-jsp-in-a-jetty-server-in-a-jar-file

I now have functional JSP pages back while running the code inside the NetBeans 14 IDE, using a ServletContextHandler instead of a WebAppContext, using a Maven shade-ed JAR with Jetty 11.0.11 and Apache JSTL and Apache JSP dependencies maven-ed in.

However, trying to run the JAR in a detached JRE via

/usr/lib/jvm/jdk-17/bin/java -Djavax.net.ssl.trustStore=/usr/lib/jvm/jdk-17/lib/security/cacerts -cp /usr/src/verdi/verdi-12-JDK17.jar verishare.App

results in

2022-09-08 14:09:32.468 INFO  WebHost - s50olqraghgm - Web Root URI:
2022-09-08 14:09:32.485 ERROR WebHost - s50olqraghgm - Runtime  exception in WebHost.java startJetty method.
java.lang.IllegalArgumentException: URI is not absolute
        at java.net.URL.fromURI(URL.java:721) ~[?:?]
        at java.net.URI.toURL(URI.java:1139) ~[?:?]
        at org.eclipse.jetty.util.resource.Resource.newResource(Resource.java:90) ~[verdi-12-JDK17.jar:11.0.11]
        at verishare.webServer.WebHost.startJettyb(WebHost.java:356) [verdi-12-JDK17.jar:11.0.11]
        at verishare.webServer.WebHost.<init>(WebHost.java:76) [verdi-12-JDK17.jar:11.0.11]
        at verishare.App.main(App.java:258) [verdi-12-JDK17.jar:11.0.11]
2022-09-08 14:09:32.491 ERROR WebHost - s50olqraghgm - WebHost class - Jetty start FAILED due to an exception! Aborting. Cannot function without Jetty! Contact Software Support.
java.lang.IllegalArgumentException: URI is not absolute
        at java.net.URL.fromURI(URL.java:721) ~[?:?]
        at java.net.URI.toURL(URI.java:1139) ~[?:?]
        at org.eclipse.jetty.util.resource.Resource.newResource(Resource.java:90) ~[verdi-12-JDK17.jar:11.0.11]
        at verishare.webServer.WebHost.startJettyb(WebHost.java:356) ~[verdi-12-JDK17.jar:11.0.11]
        at verishare.webServer.WebHost.<init>(WebHost.java:76) [verdi-12-JDK17.jar:11.0.11]
        at verishare.App.main(App.java:258) [verdi-12-JDK17.jar:11.0.11]

WebHost.java:356 is

context.setBaseResource(Resource.newResource(webRootUri));            

E. g. obviously I still have the same problem with running in the produced JAR in a detached JRE anywhere outside the NetBeans 14 JVM. This is obviously for the reasons you already explained, but how to definitively fix the jetty startup code so that it can find and parse resources from the "real" JAR when "actually" running from it (and not having been started by Maven in the NetBeans 14 realm...)

Effectively I still therefore have exactly the same problem that initially prompted the bug report...

lorban commented 2 years ago

This log is strange:

2022-09-08 14:09:32.468 INFO  WebHost - s50olqraghgm - Web Root URI:

your Web Root URI seems to be blank which would explain your present problem: Resource.newResource() internally tries to convert the URI into a URL, but that only works with absolute URIs.

You should try simplifying the way you configure your static folder:

URL webRootUrl = cl.getResource("static");
localLogger.info((String) logEntryRefNumLocal.get() + "Web Root URL:" + webRootUrl);
context.setBaseResource(Resource.newResource(webRootUrl));

See if this helps.

StefanViljoen commented 2 years ago

This log is strange:

2022-09-08 14:09:32.468 INFO  WebHost - s50olqraghgm - Web Root URI:

Yes I noted that too...

your Web Root URI seems to be blank which would explain your present problem: Resource.newResource() internally tries to convert the URI into a URL, but that only works with absolute URIs.

You should try simplifying the way you configure your static folder:

URL webRootUrl = cl.getResource("static");
localLogger.info((String) logEntryRefNumLocal.get() + "Web Root URL:" + webRootUrl);
context.setBaseResource(Resource.newResource(webRootUrl));

See if this helps.

Did the above, no change. That variable remains a zero-length string, resulting in the same exception.

Can I simply hardcode that string maybe? (I guess that will not work either.)

Much obliged.

StefanViljoen commented 2 years ago

@lorban here's my startup method that currently fails after applying the above kind suggestion:

public boolean startJettyc(Server server) throws Exception, InterruptedException {
        boolean retVal = false;

        try {
            localLogger.info((String) logEntryRefNumLocal.get() + "Starting Jetty on port " + AppSettings.getJettyServerPort() + ".");

            server = new Server(AppSettings.getJettyServerPort());

            jettyServer = server;

            server.setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize", -1);

            ServerConnector connector = new ServerConnector(server);
            server.addConnector(connector);

            String target = "JAR";

            URI webRootUri = null;

            URL webRootUrl = null;

            ClassLoader cl = WebHost.class.getClassLoader();

            if (target.equals("JAR")) {
                webRootUrl = cl.getResource("static");

                localLogger.info((String) logEntryRefNumLocal.get() + "Web Root URL:" + webRootUrl);
            } else {
                URL f = cl.getResource("static/index.html");

                if (f == null) {
                    throw new RuntimeException("Unable to find resource directory");
                }

                webRootUri = f.toURI().resolve("./").normalize();

                localLogger.info((String) logEntryRefNumLocal.get() + "Web Root URI:" + webRootUri);
            }

            ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
            context.setContextPath("/");

            context.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");

            if (target.equals("JAR")) {
                context.setBaseResource(Resource.newResource(webRootUrl));
            } else {
                context.setBaseResource(Resource.newResource(webRootUri));
            }

            SecurityHandler basicSecurity = getBasicAuthHandler("abc", "def");
            context.setSecurityHandler(basicSecurity);

            context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");

            ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
            holderPwd.setInitParameter("dirAllowed", "true");
            context.addServlet(holderPwd, "/");

            enableEmbeddedJspSupport(context);

            ServletContextHandler provisionContext = new ServletContextHandler();
            provisionContext.setContextPath("/conf");
            provisionContext.addServlet(new ServletHolder(new WebPhoneConfigurator()), "/*");

            ServletContextHandler servletContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
            servletContext.setMaxFormKeys(1000000000);
            servletContext.setContextPath("/api");
            servletContext.addServlet(new ServletHolder(new WebApiServlet()), "/*");

            String cn = "";

            Reflections rf = new Reflections("verishare");
            Set<Class<?>> classWithPath = rf.getTypesAnnotatedWith(javax.ws.rs.Path.class);
            for (Class c : classWithPath) {
                if (cn.length() > 0) {
                    cn += ";";
                }
                cn += c.getCanonicalName();

                localLogger.info((String) logEntryRefNumLocal.get() + "Adding class: " + c.getCanonicalName());
            }

            File tmpFile = new File("tmpdata");
            if (!tmpFile.exists()) {

                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder not found - creating...");

                tmpFile.mkdir();

                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder created.");
            } else {
                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder found - deleting existing files inside it...");

                for (File file : tmpFile.listFiles()) {
                    file.delete();
                }

                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder cleared of contents.");
            }

            localLogger.info((String) logEntryRefNumLocal.get() + "Setting temp file context and instantiating temp file servlet...");

            ServletContextHandler tempFileContext = new ServletContextHandler();
            tempFileContext.setContextPath("/tmpdata");
            tempFileContext.addServlet(new ServletHolder(new TempFileServlet()), "/*");

            localLogger.info((String) logEntryRefNumLocal.get() + "Temp file context set and temp file servlet instantiated.");

            localLogger.info((String) logEntryRefNumLocal.get() + "Setting Jetty handlers for all instantiated Jetty contexts...");

            StatisticsHandler statsHandler = new StatisticsHandler();
            statsHandler.setHandler(context.getServletHandler());

            HandlerList handlers = new HandlerList();
            handlers.setHandlers(new Handler[]{servletContext, provisionContext, tempFileContext, context, statsHandler});

            server.setHandler(handlers);

            //Turn off server identification
            HttpConfiguration httpConfig = new HttpConfiguration();
            httpConfig.setSendServerVersion(false);
            HttpConnectionFactory httpFactory = new HttpConnectionFactory(httpConfig);
            ServerConnector httpConnector = new ServerConnector(server, httpFactory);
            httpConnector.setPort(AppSettings.getJettyServerPort());
            server.setConnectors(new Connector[]{httpConnector});

            server.setStopAtShutdown(true);
            server.setStopTimeout(0x2710L);

            server.start();

            localLogger.info((String) logEntryRefNumLocal.get() + "Jetty Server started!");

            retVal = true;
        } catch (InterruptedException iex) {
            localLogger.error((String) logEntryRefNumLocal.get() + "InterrupedException in WebHost.java startJetty method.", iex);

            retVal = false; //Belt and suspenders

            throw iex;
        } catch (RuntimeException rex) {
            localLogger.error((String) logEntryRefNumLocal.get() + "Runtime  exception in WebHost.java startJetty method.", rex);

            retVal = false;

            throw rex;
        } catch (Exception ex) {
            localLogger.error((String) logEntryRefNumLocal.get() + "General exception in WebHost.java startJetty method.", ex);

            retVal = false;

            throw ex;
        }

        return retVal;
    }
StefanViljoen commented 2 years ago

@lorban Ok, tried to hardcode the URL, as I suspected that doesn't work either:

webRootUrl = cl.getResource("jar:file:///usr/src/verdi/verdi-12-JDK17.jar!/static");

webRootURL now resolves to null:

.
.
.
2022-09-08 16:17:26.046 INFO  WebHost - vbhdht6mah4p - WebHost class - Starting jetty...
2022-09-08 16:17:26.062 INFO  WebHost - vbhdht6mah4p - Starting Jetty on port 80.
2022-09-08 16:17:26.102 INFO  WebHost - vbhdht6mah4p - Web Root URL is 'null'
.
.
.

Surely it is possible for Jetty to read a resource from a .JAR -without- using

String webDir = Main.class.getClassLoader().getResource("static").toExternalForm();

(which doesn't work either) and is Bad Code according to @joakime but that at least returns

jar:file:///usr/src/verdi/verdi-12-JDK17.jar!/static

None of the examples I could so far find or get from seem to work at all for reading static resources from a JAR into either a Jetty WebAppContext or a ServletContextHandler.

@joakime any comment? I don't disagree it is possible, but so far in practical reality, iteration after iteration, that is -exactly- the case... Jetty cannot read resources out of a JAR - Maven shaded and cleaned up, or not...

The old saw - it all works 100% perfectly in the IDE but it simply does not work at all if you run it outside the IDE maven-executed environment in a detached JAR. E. g. the problem now really does appear to be (after eliminating the corrupted & polluted Maven / JAR setup I had, and switching away from a WebAppContext instance) that Jetty 11.0.11 apparently cannot find, or read, resources from the same JAR it is embedded in, without using toExternalForm()?

lorban commented 2 years ago

The following line is incorrect:

webRootUrl = cl.getResource("jar:file:///usr/src/verdi/verdi-12-JDK17.jar!/static");

ClassLoader.getResource() takes a resource name, not a URI string as parameter. If you would like to hardcode the URL, you have to do it this way:

webRootUrl = new URL("jar:file:///usr/src/verdi/verdi-12-JDK17.jar!/static");

One extra step you could take to figure out what Jetty can see from your static folder is to use the Resource object yourself before passing it to the context:

Resource resource = Resource.newResource(webRootUrl);
System.out.println(Arrays.toString(resource.list())); // print all files contained in the directory
context.setBaseResource(resource);

If the above code manages to print the contents of the directory (this should work both for jar files and filesystems) then the problem is not about finding your static files but rather serving them.

StefanViljoen commented 2 years ago

@lorban @joakime

That worked!

At last. THANK YOU VERY MUCH.

Using the above guidance, by hardcoding the jar: URL for cases where the code must run in the datched JRE in Linux the deatched JRE can now find the required resources from the jar while running outside the realm of the IDE...

So it is now working.

Thank you very much for the assistance guys.

Here's my final Jetty startup procedure for my Maven shade-ed JAR that now does work in both the IDE (if set to IDE mode) and the detached JRE (if set to JRE mode):

public boolean startJettyc(Server server) throws Exception, InterruptedException {
        boolean retVal = false;

        try {
            localLogger.info((String) logEntryRefNumLocal.get() + "Starting Jetty on port " + AppSettings.getJettyServerPort() + ".");

            server = new Server(AppSettings.getJettyServerPort());

            jettyServer = server;

            server.setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize", -1);

            ServerConnector connector = new ServerConnector(server);
            server.addConnector(connector);

            String target = "IDE";

            URI webRootUri = null;

            URL webRootUrl = null;

            ClassLoader cl = WebHost.class.getClassLoader();

            if (target.equals("JAR")) {               
                webRootUrl = new URL("jar:file:///usr/src/verdi/verdi-12-JDK17.jar!/static");

                localLogger.info((String) logEntryRefNumLocal.get() + "Web Root URL is \'" + webRootUrl +"\'");
            } else {
                URL f = cl.getResource("static/index.html");

                if (f == null) {
                    throw new RuntimeException("Unable to find resource directory");
                }

                webRootUri = f.toURI().resolve("./").normalize();

                localLogger.info((String) logEntryRefNumLocal.get() + "Web Root URI:" + webRootUri);
            }

            ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
            context.setContextPath("/");

            context.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");

            if (target.equals("JAR")) {
                Resource resource = Resource.newResource(webRootUrl);

                localLogger.info((String) logEntryRefNumLocal.get() + Arrays.toString(resource.list()));

                context.setBaseResource(resource);
            } else {
                context.setBaseResource(Resource.newResource(webRootUri));
            }

            SecurityHandler basicSecurity = getBasicAuthHandler("abc", "def");
            context.setSecurityHandler(basicSecurity);

            context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");

            ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
            holderPwd.setInitParameter("dirAllowed", "true");
            context.addServlet(holderPwd, "/");

            enableEmbeddedJspSupport(context);

            ServletContextHandler provisionContext = new ServletContextHandler();
            provisionContext.setContextPath("/conf");
            provisionContext.addServlet(new ServletHolder(new WebPhoneConfigurator()), "/*");

            ServletContextHandler servletContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
            servletContext.setMaxFormKeys(1000000000);
            servletContext.setContextPath("/api");
            servletContext.addServlet(new ServletHolder(new WebApiServlet()), "/*");

            String cn = "";

            Reflections rf = new Reflections("verishare");
            Set<Class<?>> classWithPath = rf.getTypesAnnotatedWith(javax.ws.rs.Path.class);
            for (Class c : classWithPath) {
                if (cn.length() > 0) {
                    cn += ";";
                }
                cn += c.getCanonicalName();

                localLogger.info((String) logEntryRefNumLocal.get() + "Adding class: " + c.getCanonicalName());
            }

            File tmpFile = new File("tmpdata");
            if (!tmpFile.exists()) {

                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder not found - creating...");

                tmpFile.mkdir();

                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder created.");
            } else {
                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder found - deleting existing files inside it...");

                for (File file : tmpFile.listFiles()) {
                    file.delete();
                }

                localLogger.info((String) logEntryRefNumLocal.get() + "Web-accessible temp data folder cleared of contents.");
            }

            localLogger.info((String) logEntryRefNumLocal.get() + "Setting temp file context and instantiating temp file servlet...");

            ServletContextHandler tempFileContext = new ServletContextHandler();
            tempFileContext.setContextPath("/tmpdata");
            tempFileContext.addServlet(new ServletHolder(new TempFileServlet()), "/*");

            localLogger.info((String) logEntryRefNumLocal.get() + "Temp file context set and temp file servlet instantiated.");

            localLogger.info((String) logEntryRefNumLocal.get() + "Setting Jetty handlers for all instantiated Jetty contexts...");

            StatisticsHandler statsHandler = new StatisticsHandler();
            statsHandler.setHandler(context.getServletHandler());

            HandlerList handlers = new HandlerList();
            handlers.setHandlers(new Handler[]{servletContext, provisionContext, tempFileContext, context, statsHandler});

            server.setHandler(handlers);

            //Turn off server identification
            HttpConfiguration httpConfig = new HttpConfiguration();
            httpConfig.setSendServerVersion(false);
            HttpConnectionFactory httpFactory = new HttpConnectionFactory(httpConfig);
            ServerConnector httpConnector = new ServerConnector(server, httpFactory);
            httpConnector.setPort(AppSettings.getJettyServerPort());
            server.setConnectors(new Connector[]{httpConnector});

            server.setStopAtShutdown(true);
            server.setStopTimeout(0x2710L);

            server.start();

            localLogger.info((String) logEntryRefNumLocal.get() + "Jetty Server started!");

            retVal = true;
        } catch (InterruptedException iex) {
            localLogger.error((String) logEntryRefNumLocal.get() + "InterrupedException in WebHost.java startJetty method.", iex);

            retVal = false; //Belt and suspenders

            throw iex;
        } catch (RuntimeException rex) {
            localLogger.error((String) logEntryRefNumLocal.get() + "Runtime  exception in WebHost.java startJetty method.", rex);

            retVal = false;

            throw rex;
        } catch (Exception ex) {
            localLogger.error((String) logEntryRefNumLocal.get() + "General exception in WebHost.java startJetty method.", ex);

            retVal = false;

            throw ex;
        }

        return retVal;
    }
StefanViljoen commented 2 years ago

For completeness sake (and in case someone with a similar issue searches here later) the

enableEmbeddedJspSupport(context);

line in the code above refers to this method, which enables JSP functionality in the ServletContextHandler (used instead of WebappContext) above (found on stackoverflow - missing the link no though):

private static void enableEmbeddedJspSupport(ServletContextHandler servletContextHandler) throws IOException {
        // Establish Scratch directory for the servlet context (used by JSP compilation)
        File tempDir = new File(System.getProperty("java.io.tmpdir"));
        File scratchDir = new File(tempDir.toString(), "embedded-jetty-jsp");

        if (!scratchDir.exists()) {
            if (!scratchDir.mkdirs()) {
                throw new IOException("Unable to create scratch directory: " + scratchDir);
            }
        }
        servletContextHandler.setAttribute("javax.servlet.context.tempdir", scratchDir);

        ClassLoader jspClassLoader = new URLClassLoader(new URL[0], WebHost.class.getClassLoader());
        servletContextHandler.setClassLoader(jspClassLoader);

        servletContextHandler.addBean(new JspStarter(servletContextHandler));

        ServletHolder holderJsp = new ServletHolder("jsp", JettyJspServlet.class);
        holderJsp.setInitOrder(0);
        holderJsp.setInitParameter("logVerbosityLevel", "DEBUG");
        holderJsp.setInitParameter("fork", "false");
        holderJsp.setInitParameter("xpoweredBy", "false");
        holderJsp.setInitParameter("compilerTargetVM", "1.8");
        holderJsp.setInitParameter("compilerSourceVM", "1.8");
        holderJsp.setInitParameter("keepgenerated", "true");
        servletContextHandler.addServlet(holderJsp, "*.jsp");
    }