Tomcat deployment and use in IDEA works, but 404 when deployed to server
已回答
I do Run->Edit Configurations and deploy my web application to Tomcat in IDEA. It works perfectly for my GET and POST.
When I take the resulting WAR file and drop it into a "real" systemd Tomcat service, it deploys, but GETting from it or POSTing to it produce nothing but 404.
What should I look for in trying to solve this problem?
----------
IntelliJ IDEA Ultimate 2018.1.4
Oracle JDK 1.8.0-144
Tomcat 9.0.8
JAX-RS Jersey
请先登录再写评论。
(Yes, I am using Maven to build it.)
Check the context under which the web app is deployed from IntelliJ IDEA and from the command line, it can be different so the URL would be different.
First, thank you very much for responding.
Where do I go to check this "context" in IDEA? This is my first servlet in IDEA (my others, years ago, were done in Eclipse, so I'm learning new stuff here). Because you'll likely sleep before answering this, let me add some detail. Remember, all of this works perfectly in IDEA (port 9090), but not against my systemd service (port 8080):
- web.xml excerpt:
<servlet>
<servlet-name>mdht-restlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.imatsolutions.servlet</param-value>
</init-param>
<servlet-mapping>
<servlet-name>mdht-restlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
- Servlet code has @Path( "/mdht-restlet" ) at top.
- Posting to URL: http://localhost:8080/mdht-restlet/ using postman utility in browser.
- I see this in catalina.out when I do the POST, but I don't think it's really an error:
14-Jun-2018 16:17:25.822 INFO [http-nio-8080-exec-1] com.sun.jersey.api.core.PackagesResourceConfig.init Scanning for root resource and provider classes in the packages:
com.imatsolutions.servlet
14-Jun-2018 16:17:25.836 INFO [http-nio-8080-exec-1] com.sun.jersey.api.core.ScanningResourceConfig.logClasses Root resource classes found:
class com.imatsolutions.servlet.MdhtRestlet
14-Jun-2018 16:17:25.836 INFO [http-nio-8080-exec-1] com.sun.jersey.api.core.ScanningResourceConfig.init No provider classes found.
14-Jun-2018 16:17:25.888 INFO [http-nio-8080-exec-1] com.sun.jersey.server.impl.application.WebApplicationImpl._initiate Initiating Jersey application, version 'Jersey: 1.19.1 03/11/2016 02:42 PM'
Please see my answer here: https://stackoverflow.com/a/15511476/104891.
May I reiterate? I do not have the problem that the stackoverflow.com question was asking.This all works in IntelliJ IDEA. However, it does not work when I drop mdht-restlet.war into /opt/tomcat/webapps. The deployment works, but the same URL, localhost:8080/mdht-restlet/ does not (while, for Tomcat launched from IDEA, localhost:9090/mdht-restlet/, does work). From my point of view examining the two Tomcat deployments, the one in IDEA magically works while the one in the standard systemd service does not.
In short, what my pom.xml builds isn't what IDEA is building. What is the relationship between IDEA and my pom.xml? I know that when I modify it, IDEA tells me Maven projects need to be imported (and I click Import Changes), but how closely does IDEA implement what's in pom.xml versus what IDEA must be doing with Edit Run Configurations?
I'm completely mystified: I never had this "difference" in Eclipse. I don't know what I've done wrong. Clearly, I've done things right in IDEA, but I have to build this web application at the command line (and using Jenkins), so even if I could generate the WAR file from IDEA, it would not be the right thing to do.
Again, I'm very grateful for you assistance.
IntelliJ IDEA artifact build system is not 100% copy of what Maven builds. Depending on your pom.xml and plugins used there can be various differences in the produced artifacts.
Usually the issue is that IntelliJ IDEA artifact doesn't work while Maven artifact works fine because of some unsupported option/plug-in in pom.xml.
Does the artifact built with the command line Maven work properly when deployed manually to the same Tomcat? Is the issue specific to the artifact that is built by IntelliJ IDEA instead of Maven?
To investigate this problem further we'll need the sample project to reproduce it.
Thank you, look here:
http://windofkeltia.com/preview/
for a tarball. Now, for some reason, when you explode that tarball and load the project into IDEA, the Run/Debug Configuration is missing. At that same URL, I have .png images of the configuration.
To answer your question, I am using Tomcat 9.0.8 in IDEA and I have installed it (on my Linux Mint development host) as a systemd service. No, the WAR file artifact, under target, does not work (it deploys and runs, but I can't get it to work--this is my question). I think the answer to your second question is that I don't know how to build an artifact with IDEA. I use IDEA to run/debug and it all works fine. I use command-line Maven to build the production artifact, which does not work.
Temporarily, ...
If there is a way to generate a WAR file from IDEA, and it worked identically to what I'm experiencing in IDEA, I could use that in early days. Long-term I have to be able to build in Jersey (without IDEA) and I can just as I build from the command line, but I can do without that for a week or two if I can at least get a working WAR file directly out of IDEA.
When I do
find . -name '*.war'
I only see the one I built using Maven (under target). Where are these artifacts that IDEA builds? Are they WARs?
See https://www.jetbrains.com/help/idea/artifacts.html .
If the artifact built with Maven doesn't work, the issue is not specific to IntelliJ IDEA and http://stackoverflow.com/ would be a better place to ask for help how to properly configure your Maven project so that it builds the correct war from the command line.
It turns out that if I rename mdht-restlet.war to ROOT.war, then drop it into webapps, everything works. This might mean that IntelliJ IDEA run configuration settings work some magic that I don't get when leaving the IDE behind to go to the server container. Makes perfect sense. So, your first answer was sort of headed that direction. I'm going to have to go figure out how to configure Tomcat.
Thanks, Serge!
IntelliJ IDEA instructs Tomcat to deploy under the specified context (which is ROOT or `/` by default).
When you place the war to webapps to deploy manually, it will be deployed under the context corresponding to the war file name.
Therefore, all the URLs you are using must be prepended with the context the web app is deployed under.
localhost:8080/mdht-restlet/ working in IntelliJ IDEA becomes localhost:8080/mdht-restlet/mdht-restlet when deployed externally.
There is no magic here. So yes, my first comment is exactly about that.
I have encountered the same problem. On the remote server, I tried [ip and port] / [folder-name-in-webapps] / [application-context] but I still get 404. Is this what you meant in the comment above? I also tried renaming the war folder to ROOT and typing [ip and port] / [application-context] but I still get 404.
Dylansijanivandi Please share any sample project to reproduce the issue and the screenshots of the run/debug configuration (all the tabs including Deployment) + the logs of the output console in the IDE. The files can be uploaded at https://uploads.jetbrains.com.
Upload id: 2021_01_25_BGE24xnQzg2DD1fm (file: Spring MVC and WebFlux.zip)
Upload id: 2021_01_25_4UGdzLKrfZadCuoH (files: DeplymentTab.png, RunConfig-ServerTab.png)
Upload id: 2021_01_25_EW8UQrV1axmCDqcc (files: output console.png and 4 more)
Thanks for the details. It looks like you are using deployment to the remote server and the console says the the deployment was successful. Could you please look for the Tomcat server logs on the remote system, zip and upload them as well?
Upload id: 2021_01_25_FpUgfqFgEuZCnMqX (file: catalina.out)
Is the problem specific to the remote deployment? Does it work correctly if you deploy the app using Local tomcat configuration?
And for the remote server, does the app start without issues if you copy the .war file to webapps manually without using IntelliJ IDEA?
There is an exception in the catalina.out which may be related to the problem, but it's not clear why it occurs. Reproducing this issue would require some time as we don't have a similar environment with CentOS and Tomcat were the remote deployment can be tested.
What JDK is used to run Tomcat server on CentOS?
I've managed to reproduce the issue and the most likely cause is the JDK version you are using to run Tomcat.
You probably have the following in Tomcat logs:
It means that it can't load BookstoreWebApplicationInitializer that you are deploying.
The sample project imported from Gradle targets Java version 14. If Tomcat on the remote server runs on a lower Java version, it will not be able to load classes compiled for the higher Java version.
The solution is to either configure Tomcat to run on Java 14+ or configure the project to target the Java version Tomcat is using.
For example, if Tomcat runs on Java 11 and you don't want to change it, change the build.gradle to the following and reimport the project:
So, the issue is not related to IntelliJ IDEA, but to the JDK incompatibility between the project and the remote server.
The reason it works in IntelliJ IDEA if you start it locally is that it uses the same project JDK to start local Tomcat and it has no problem loading classes targeting this Java version.
I updated the server JRE from 8 to 15 but the problem persists. In the tomcat manager GUI I saw that the webapp isn't running, and when I click the webapp start button I get an exception.
Could be some incompatibility of Tomcat and Java 15.
Try using Java 11 and set the target language level to 11 as well, rebuild the project. It works perfectly for me.
Before changing both the server and the project to Java 11 as you suggested, for expedience I tried just changing the project to Java 15 to match the Server's Java 15 JRE, which also worked. I tried switching the project back to jdk 14 and now jdk 14 suddenly works with the server's JRE 15. Tomcat hasn't stopped running since my last comment, so if updating the server to JRE 15 was the solution then why did the solution not take affect at the time of my last comment? The only variable was me changing the project jdk to 15 and back to 14, so I presume whatever went wrong must've happened during this process in Intellij.
Sorry, I have no idea why it didn't work first time. Glad that it works fine now.
Hello,
I'm struggling with the same problem as Russell Bateman.
When manually deployed a .war file (Rest API), I get 404 when try to access the endpoint. Deployed through Intellij it works perfectly fine.
The manual deployment only works properly If I change the name to Root.war.
Is there any solution to this problem so far?
Kdzekov
What version of Java and Tomcat is used? Do you use Gradle or Maven?
Are there any exceptions in the Tomcat logs?
Did you check to see if the application context is correct?
Please share a demo project to reproduce the issue, and the screenshots of the Run/Debug Configuration (all the tabs including Deployment) + logs of the output console in the IDE. The files can be uploaded at https://uploads.jetbrains.com