jetty/jetty.project

how run project that its main class is in another jar file instead of war file

Closed this issue · 10 comments

Jetty Version
12
Jetty Environment
ee10

Java Version
21
Question
The project that I migrated from Jetty 9 to Jetty 12 is a large project with about 24 modules. During the build process, one of these modules builds as war file and the others as jar files.
In the deployment process of the previous version of the project on Jetty 9, these jar files were placed in different paths in Jetty 9, and some of them were introduced to the project with the -Djava.library.path command, and some of them were introduced in the WebAppContext introduction section by <Set name="extraClasspath">...</Set> config in jetty.xml file.

in deploy command: -Djava.library.path:/opt/ch/lib
in jetty.xml file : <Set name="extraClasspath>/opt/ch/lib/jars/store.jar,/opt/ch/lib/jars/client.jar,/opt/ch/lib/jars/soap.jar</Set>

The main class that must be executed when deploying is not in war file, but in store.jar file.
In Jetty 9, when I deploy the previous version, it goes to that class and executes its method and displays the logs related to its execution.

Now in Jetty 12, I have introduced these jar files to the project in the same way as above. But in Jetty 12 and with the current version of the project, it seems that only the war file comes up and the main class in store.jar does not executed.

I check with --list-config command, but I don't see any traces of these jar files in classpath.

The jars you are adding via extraClasspath wouldn't show up in --list-config as that will only show jar files that either exist on the server classloader or the environment specific classloaders.

Use start.jar jetty.server.dumpAfterStart=true and copy/paste that output into this issue.
Please don't remove lines from the output, but feel free to XX out any information that you might feel is private.

@joakime
This command threw about 9000 log lines.
Unfortunately, it is on a server that I do not have copy access to
What parts of this log do you think are important that I should pay attention to?

In the Store.jar file(As I said, the main and primary class of program implementation is located there), there is a method named startup, which must be called during project deployment, but there is no trace of it in these logs.

The main class that must be executed when deploying is not in war file, but in store.jar file.

What does this mean?
By "main class" you mean a class with a main(String[]) method?

Deployment of web applications is performed by Jetty, and it is not done via a main class.

You cannot put a main class in a war file and expect to be executed by Jetty.

Please detail exactly what you're trying to do, and we might be able to help you.

@sbordet
By main class I don't mean class with main(String[]) method. I mean a class from which a method must be executed when the project is deployed and server is started.
I am not very expert in English. Maybe I can hardly get my point across.

When I checked the code better, I realized that this method is called in the init() method of a servlet, and the reason why this method is not called is that none of the servlets configured in the web.xml file are initialized when the server is started, although load-on-startup configs are set for them.
In jetty 12, is there any special configuration required for the servlet to be initialized when the server starts?

When I checked the code better, I realized that this method is called in the init() method of a servlet, and the reason why this method is not called is that none of the servlets configured in the web.xml file are initialized when the server is started, although load-on-startup configs are set for them.

This is highly unlikely, we have a million tests for this.

You have something else wrong in your configuration, which you did not detail.

@sbordet , @joakime
I finally understood what my mistake was.
I had created a Context XML file in $JETTY_BASE/webapp path with the following configs:

<Configure id="service" class="org.eclipse.jetty.ee10.webapp.WebAppContext">
  <Set name="war"> <SystemProperty name="jetty.base" default="."/>/webapps/service</set>
   <Set name="contextPath" >/service</set>
  <!-- other configs -->
</Configure>

And I also had an service folder in $JETTY_BASE/webapp path that contained service.war file, which I had not entered in the above configs in the continuation of <Set name="war"> path.

<Set name="war"> <SystemProperty name="jetty.base" default="."/>/webapps/service/service.war</set>

In fact, I had written /webapps/service instead of /webapps/service/service.war

So, probably, I was introducing an empty directory to Jetty as a project, and that's why the servlets in the web.xml file were not initialized because they were not introduced to Jetty at all.
Is this my conclusion correct?

Now that I have also added /service.war in <Set name="war">...</Set> . During deployment, the project stops right after it writes in the log that it started,
The last few lines of the log:

.......
2024-08-07 00:01:15.798:WARN:oejea.AnnotationParser:qtp1578009262-40: com.cha.license.ChaLicenseManager$1 scanned from multiple locations: jar:file:///opt/ch/lib/jars/store.jar!/com/cha/license/ChaLicenseManager$1.class, jar:file:///opt/ch/lib/jars/store.jar!/com/cha/license/ChaLicenseManager$1.class  
2024-08-07 00:01:15.933:WARN : oatud.DigesterFactory:main: The XML schema [XMLSchema.dtd] **could not be found**. This is very likely to break XML validation if XML validation is **enabled**.  
2024-08-07 00:01:15.934:WARN : oatud.DigesterFactory:main: The XML schema [datatypes.dtd] **could not be found**. This is very likely to break XML validation if XML validation is **enabled**.  
2024-08-07 00:01:15.934:WARN : oatud.DigesterFactory:main: The XML schema [xml.xsd] **could not be found**. This is very likely to break XML validation if XML validation is **enabled**.  
2024-08-07 00:01:16.020:INFO :oejsh.ContextHandler:main: Started oeje10w.WebAppContext@3350ebdd{Ch Service,/service,b=file:///opt/ch/jetty_base/webapps/service/,a=AVAILABLE, h=oeje10s.SessionHandler@42fcc7e6{STARTED}}{/opt/ch/mailboxd/webapps/service}  
[16.186s] [info] [gc] GC(10) Pause Young (Concurrent Start) (Metadata GC Threshold) 307M->155M(2048M) 14.970ms  
[16.186s] [info] [gc] GC(11) Concurrent Mark Cycle  
[16.242s] [info] [gc] GC(11) Pause Remark 158M->143M(2048M) 14.267ms  
[16.263s] [info] [gc] GC(11) Pause Cleanup 144M->144M(2048M) 0.766ms  
[16.273s] [info] [gc] GC(11) Concurrent Mark Cycle 86.782ms  
ch@mail.sena.ir:~$

Why is this happening?
There are no more logs for me to understand exactly what is happening
although the jetty.server.dumpAfterStart=true command is active, no log is printed in relation to this command.

Parts of web.xml file in our project:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
    xmlns="https://jakarta.ee/xml/ns/jakartaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee 
    https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
    version="6.0"
    metadata-complete="false">
    
    <display-name>Chmail Service</display-name>
    <description>SOAP Service</description>
    
    <filter>
        <filter-name>DosFilter</filter-name>
        <filter-class>com.ch.servlet.DosFilter</filter-class>
        <async-supported>true</async-supported>
        <init-param>
            <param-name>delayMa</param-name>
            <param-value>-1</param-value>
        </init-param>
        <init-param>
            <param-name>maPerSec</param-name>
            <param-value>1000</param-value>
        </init-param>
        <init-param>
            <param-name>rePort</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>mMa</param-name>
            <param-value>9223372036854775807</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>DosFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <servlet>
        <servlet-name>FirstServlet</servlet-name>
        <servlet-class>com.ch.servlet.FirstServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    
    <servlet>
        <servlet-name>ExtensionDispatcherServlet</servlet-name>
        <servlet-class>com.ch.extension.ExtensionDispatcherServlet</servlet-class>
        <init-param>
            <param-name>allowed.ports</param-name>
            <param-value>8080, 8443</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    
    <servlet>
        <servlet-name>SoapServlet</servlet-name>
        <servlet-class>com.ch.SoapServlet</servlet-class>
        <init-param>
            <param-name>allowed.ports</param-name>
            <param-value>8080, 8443</param-value>
        </init-param>
        <!-- User command handlers only -->
        <init-param>
            <param-name>engine.handler.0</param-name>
            <param-value>com.ch.account.AccountService</param-value>
        </init-param>
        <init-param>
            <param-name>engine.handler.1</param-name>
            <param-value>com.ch.mail.MailService</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
<servlet>
    <servlet-name>AdminServlet</servlet-name>
    <servlet-class>com.ch.SoapServlet</servlet-class>
    <init-param>
        <param-name>allowed.ports</param-name>
        <param-value>7071, 7073</param-value>
    </init-param>
    <!-- Admin servlet allows both admin and user commands -->
    <init-param>
        <param-name>engine.handler.0</param-name>
        <param-value>com.ch.AdminService</param-value>
    </init-param>
    <init-param>
        <param-name>engine.handler.1</param-name>
        <param-value>com.ch.account.AccountService</param-value>
    </init-param>
    <init-param>
        <param-name>engine.handler.2</param-name>
        <param-value>com.ch.mail.MailService</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
    <async-supported>true</async-supported>
</servlet>
<servlet-mapping>
    <servlet-name>FirstServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>ExtensionDispatcherServlet</servlet-name>
    <url-pattern>/extension/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>SoapServlet</servlet-name>
    <url-pattern>/soap/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>AdminServlet</servlet-name>
    <url-pattern>/ad/soap/*</url-pattern>
</servlet-mapping>
<servlet id="jsp">
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.eclipse.jetty.ee10.jap.JettyJspServlet</servlet-class>
    <init-param>
        <param-name>fork</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>xpoweredBy</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>trimSpaces</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>classpath</param-name>
        <param-value>?</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
    <async-supported>true</async-supported>
</servlet>
<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>/apnago/snoop.jap</url-pattern>
    <url-pattern>/apnago/error401.jap</url-pattern>
    <url-pattern>/error/403.jsp</url-pattern>
    <url-pattern>/error/attachment_blocked.jsp</url-pattern>
    <url-pattern>/error/sfdc_preauth.jsp</url-pattern>
</servlet-mapping>
<env-entry>
    <env-entry-name>chServicesEn</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>service,chmail,chmailAdmin,mailbox,anmp,stats,spell</env-entry-value>
</env-entry>
</web-app>

@joakime , @sbordet
Since I could not understand where the problem is, I decided to completely empty the web.xml file and add servlets and filters to it one by one and deploy each time to see where the problem is.
First of all, I added JettyJspServlet servlet to web.xml file and encountered the following error:

java.util.ServiceConfigurationError: org.apache.juli.logging.Log: org.eclipse.jetty.ee10.apache.jsp.Julilog not a subtype

I searched about this error and they wrote that if apache-jsp or tomcat-juli have duplicates, there will be a problem. I installed the maven duplicate finder plugin to detect duplicates. A series of files had this problem, but the files of apache-jsp or tomcat-juli were not among them.
Thank you for your guidance on what else I should check to fix this error.

@fgolzari sorry, but at this point we have no idea what you are doing.
In your last comment, you report problems that do not seem related to Jetty, but more to configuration mistakes in your setup.

I suggest that you re-start from scratch with the simplest possible web application, and build from there.

@sbordet Thank you for answering my questions
All issues were resolved and the project was deployed correctly and is working. thanks a lot.

Thanks for the feedback. Closing the issue.