Russell Bateman May 2018
Nota bene: This really has turned more into notes on how to use IDEA Ultimate to write web applications.
What do you do to cause Maven to build a WAR file? Add this to pom.xml:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.2.0</version> <configuration> <webResources> <resource> <!-- this is relative to the pom.xml directory --> <directory>web</directory> </resource> </webResources> </configuration> </plugin> </plugins> </build>
The <directory> specified above assumes the following structure in your project:
~/dev/hello-restlet $ tree . ├── hello-restlet.iml ├── pom.xml ├── src │ └── ... └── web └── WEB-INF └── web.xml
I downloaded IntelliJ IDEA Ultimate (here at work too) and then did Install and Configure Tomcat IntelliJ IDEA which is a year old, has no sound and is full of misleading mousing. Here I am reducing that experience to a set of steps. It did work, however, and that puts me hugely up over the experience I had with Eclipse WTP back in 2008 when I really started in earnest trying to learn to do web programming with Eclipse.
Hello viewer Please Subscribe Thanks For Waching...
This is working, so I'm going to have to spring the $150 for this IDE now.
These are practical and up-to-date instructions based on Sam Jesso's 2014 Starting out with Jersey & Apache Tomcat using IntelliJ. Here are the steps, illustrations and elaborations I followed:
<?xml version="1.0" encoding="UTF-8"?> <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>com.example.jersey</groupId> <artifactId>hello-rest</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-bundle</artifactId> <version>1.19.1</version> </dependency> </dependencies> </project>
package com.example.jersey; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path( "/hello" ) public class HelloWorld { @GET @Produces( MediaType.TEXT_PLAIN ) public String getMessage() { return "Hello world!"; } }
It is imperative that you pay close attention to the URL under Open browser below: unlike how Eclipse deploys and works, IDEA must have the URL to this degree of specificity in order to work. You will see a new tab appear in your browser with this URL and little else. If you do not have a complete URL, depending on the options of your servlet, you likely will get HTTP 404 and nothing will work.
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>Example API</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.example.jersey</param-value> </init-param> <init-param> <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Example API</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
* Optionally, you can scrape these, paste them into a simple editor like vim, gvim or gedit, then copy them from there into your new class.
As I revisit this tutorial, I discover that it no longer works because, when launched, it yields (in the browser), this error:
java.lang. TypeNotPresentException: Type javax.xml.bind.JAXBContext Exception
This is because I'm trying to use JDK11 which no longer supports Java EE and, in particular, has removed support for java.xml.bind. So, I tried adding such support to pom.xml (in addition already to Jersey):
<dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-bundle</artifactId> <version>1.19.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.3.0.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.1</version> </dependency>
This did not work or solve the issue. By Java 6, Java had built-in support for XML-based web services because they were so popular, but eventually, such decisions made Java bigger and bigger until a new trend reversed this. In Java 9 and 10, this support was deprecated, then Java 11 eliminated it altogether. The solution became to add JAXB as a dependency to the project, however, this doesn't always work as is the case above.
The solution is to find an old, JDK8 to develop with until this is sorted out by someone. (And take the dependencies above out of pom.xml.) I don't know how to solve it yet, so this is my solution.
Next up should be a tutorial on how to endow the restlet above with an index.jsp (that's meaningful and not the template one that appeared above as the result of adding frameworks) that does something.
If developing on two hosts, or if collaborating with others, you will not be maintaining .idea/workspace.xml under version control (for all sorts of reasons). Therefore, the step on creating a run/debug configuration will have to be done in every IDEA instance you run. .idea/workspace.xml is where this is kept because, in this case, it's a file-system dependent operation (i.e.: where your copy of Tomcat lives).
Misère ! I came back months later and my Jersey example no longer worked in IntelliJ IDEA. Then, I redid the hello-world tutorial and the one before that, then I played around with it and it started to work, but what did I do to make it work?
GET http://localhost:7070/mdht-servlet The MDHT restlet is up. Manifest-Version: 1.0 Implementation-Version: 1.0.0-SNAPSHOT Implementation-Vendor-Id: com.windofkeltia.mdht Build-Time: 2019-06-13T20:24:30Z Created-By: IntelliJ IDEA Build-JDK: 1.8.0_211 Specification-Version: 1.0.0-SNAPSHOT Copyright © 2018-2019 by Acme Solutions and Etretat Logiciels, LLC. Proprietary and confidential. All rights reserved. POST http://localhost:7070/mdht-servlet <?xml version="1.0" encoding="UTF-8"?> <ClinicalDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:hl7-org:v3" xsi:schemaLocation="urn:hl7-org:v3 infrastructure/cda/CDA_SDTC.xsd"> <realmCode code="US"/> <typeId root="2.16.840.1.113883.1.3" extension="POCD_HD000040"/> <templateId root="2.16.840.1.113883.10.20.22.1.2" extension="2015-08-01"/> <id root="3fe5991c-3624-40b8-9b4c-72d4db8fb5ff"/> <code code="34133-9" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC" displayName="Summarization of Episode Note"/> <title>Continuity of Care Document</title> <effectiveTime value="20190613203413+0000"/> <confidentialityCode code="N" codeSystem="2.16.840.1.113883.5.25"/> <languageCode code="en-US"/> <setId root="2.16.840.1.113883.19.5.99999.19" extension="sTT988"/> <versionNumber value="1"/> ... <entry> <observation classCode="OBS" moodCode="EVN"> <templateId root="2.16.840.1.113883.10.20.22.4.38" extension="2015-08-01"/> <templateId root="2.16.840.1.113883.10.20.22.4.38"/> <id root="497170e3-8bba-4184-9114-44fe9995baf8"/> <code code="228272008" codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOWMED CT" displayName="Health-related behavior"> <translation code="29762-2" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC" displayName="Social History"/> </code> <text> <reference value="#SOCIAL-HISTORY-612243438"/> </text> <statusCode code="completed"/> <effectiveTime value="20190613203413+0000"/> </observation> </entry> </section> </component> </structuredBody> </component> </ClinicalDocument>
I'm not certain what I've done to make this work. Here are all the details of my configuration.
The comment about the URL has to do with IDEA working and Tomcat working identically. The point is that, when Tomcat deploys, the WAR name itself (mdht-servlet.war) is already the root and part of the path. To add something (to the @Path annotation below) will only lengthen the URL again.
/** * The point of entry into this servlet. The URL at this point is already * http://localhost:8080/mdht-servlet; don't add to it. * @author Russell Bateman * @since May 2018 */ @Path( "" ) public class MdhtRestlet { ...
The servlet name can't be willy-nilly, but must match.
<servlet> <servlet-name>mdht-servlet</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> ... <servlet-mapping> <servlet-name>mdht-servlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
Project name: mdht-servlet Project SDK: 1.8 (problem with Java thereafter) Project language level: 8 - Lambdas, type annotations, etc.
Tomcat Server Name: mdht-servlet URL: http://localhost:7070/mdht-servlet HTTP port: 7070 JMX port: 1099 Deployment tab Deploy at the server startup mdht-servlet:war exploded Application context: /mdht-servlet
What's notable: the JAXB dependencies, in-project location of the parent of web.xml.
... <artifactId>mdht-servlet</artifactId> ... <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-bundle</artifactId> <version>${jersey-bundle.version}</version> </dependency> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet-api.version}</version> <scope>provided</scope> <!-- (provided by Tomcat) --> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.3.0.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.1</version> </dependency> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>${maven-war-plugin.version}</version> <configuration> <webResources> <resource> <!-- this is relative to the pom.xml directory --> <directory>web</directory> </resource> </webResources> <!-- Magic for maintaining a build timestamp in MANIFEST.MF: --> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> </manifest> <manifestEntries> <Build-Time>${maven.build.timestamp}</Build-Time> </manifestEntries> </archive> </configuration> </plugin> ...
It seems that Java has been lightened because folk have complained it's got too big in recent years. For example, JAXB (XML-binding in web applications) once seemed important to everyone and certain libraries were included by default. This was deprecated in Java 9 and 10, then, in Java 11, JEE was thrown out altogether. The problem is that bloggers are slow to catch up on how now to build something JEE (like mdht-servlet). So, I have had to a) include 3 JAXB JARs and b) return the project build to using Java 8. I don't yet know how to build it using Java 11, but I don't care too much right now.
Oh, why does it make a difference that mdht-servlet run in the IDE? Because it's much easier to debug that way than to have to deploy it to a Tomcat instance and debug it remotely.
Here is a list of things I looked at, changed and that may have a bearing on the success. Note that not all were done specifically to solve the 404; some were done to stop (JAXB) crashes or make the thing launch at all.
This is an interpretation of Part 1.1: Java EE Webapplication with servlet and JSP page.
<%-- Created by IntelliJ IDEA. User: russ Date: 5/4/18 Time: 10:25 AM To change this template use File | Settings | File Templates. Note: because this file is fetched implicitly because under the web subdirectory, even without being named in a welcome-file-list element. --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <title>Web App Tutorial Page</title> </head> <body> <h1> Hello World </h1> <p> Body text. This is my first webapp JSP page. </p> </body> </html>
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> (empty) </web-app>
<%@ page import="java.util.Date" %> <%-- Created by IntelliJ IDEA. User: russ Date: 5/4/18 Time: 10:25 AM To change this template use File | Settings | File Templates. Note: because this file is fetched implicitly because under the web subdirectory, even without being named in a welcome-file-list element. --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <title>Web App Tutorial Page</title> </head> <body> <h1> Hello World </h1> <p> Body text. This is my first webapp JSP page. </p> <% Date date = new Date(); out.print( "<h3>" + date.toString() + "</h3>" ); %> </body> </html>
<%-- Created by IntelliJ IDEA. User: russ Date: 5/4/18 Time: 10:25 AM To change this template use File | Settings | File Templates. Note: because this file is fetched implicitly because under the web subdirectory, even without being named in a welcome-file-list element. --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <title>Login Page</title> </head> <body> <h1> Welcome, please log in: </h1> <form action="/login" method="POST"> Name: <input type="text" name="username" width="30" /><br /> Password: <input type="password" name="password" width="10" /><br /> <input type="submit" value="login" /> </form> </body> </html>
package webapp; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet( name = "Login" ) public class Login extends HttpServlet { protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { } protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> Login webapp.Login Login /login </web-app>
protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String username = request.getParameter( "username" ); String password = request.getParameter( "password" ); PrintWriter out = response.getWriter(); out.println( "Username: " + username ); out.println( "Password: " + password ); }
protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String username = request.getParameter( "username" ); String password = request.getParameter( "password" ); PrintWriter out = response.getWriter(); out.println( "From POST'd form:" ); out.println( "Username: " + username ); out.println( "Password: " + password ); }
<%-- Created by IntelliJ IDEA. User: russ Date: 5/7/18 Time: 3:09 PM To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title> Welcome </title> </head> <body> <h1> Welcome </h1> <p> Dear: ${username}, your password is ${password}. <!-- (${} is called "expression language") --> </p> </body> </html>
package webapp; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet( name = "Login" ) public class Login extends HttpServlet { private static final String QPARM_USERNAME = "username"; private static final String QPARM_PASSWORD = "password"; private static final String JSP_USERNAME = "username"; private static final String JSP_PASSWORD = "password"; protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { request.setAttribute( JSP_USERNAME, request.getParameter( QPARM_USERNAME ) ); request.setAttribute( JSP_PASSWORD, request.getParameter( QPARM_PASSWORD ) ); request.getRequestDispatcher( "/welcome.jsp" ).forward( request, response ); } protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws IOException { String username = request.getParameter( QPARM_USERNAME ); String password = request.getParameter( QPARM_PASSWORD ); PrintWriter out = response.getWriter(); out.println( "Username: " + username ); out.println( "Password: " + password ); } }
package pojo; public class User { private String username; private String password; public User( final String username, final String password ) { this.username = username; this.password = password; } public boolean isValidUsername() { return username.equals( "russ" ); } public boolean isValidPassword() { return password.equals( "snagglepuss" ); } }
private static final String QPARM_USERNAME = "username"; private static final String QPARM_PASSWORD = "password"; private static final String JSP_USERNAME = "username"; private static final String JSP_PASSWORD = "password"; private static final String INVALID_USERNAME = "username is unknown"; private static final String INVALID_PASSWORD = "password was wrong"; protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String username = request.getParameter( QPARM_USERNAME ); String password = request.getParameter( QPARM_PASSWORD ); User user = new User( username, password ); String errors = ""; if( !user.isValidUsername() ) errors += " " + INVALID_USERNAME + " (" + username + ")<br />"; else if( !user.isValidPassword() ) errors += " " + INVALID_PASSWORD + " (" + password + ")<br />"; if( errors.length() < 1 ) { request.setAttribute( JSP_USERNAME, request.getParameter( QPARM_USERNAME ) ); request.setAttribute( JSP_PASSWORD, request.getParameter( QPARM_PASSWORD ) ); request.getRequestDispatcher( "/welcome.jsp" ).forward( request, response ); } else { request.setAttribute( "error_message", "Invalid login:<br />" + errors + "Please try again." ); request.getRequestDispatcher( "/login.jsp" ).forward( request, response ); } }
<%-- Created by IntelliJ IDEA. User: russ Date: 5/4/18 Time: 10:25 AM To change this template use File | Settings | File Templates. Note: because this file is fetched implicitly because under the web subdirectory, even without being named in a welcome-file-list element. --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <title>Login Page</title> </head> <body> <h1> Welcome, please log in: </h1> <form action="/login" method="POST"> Name: <input type="text" name="username" width="30" /><br /> Password: <input type="password" name="password" width="10" /><br /> <input type="submit" value="Log in" /> </form> <p> <span style="color: red"> ${error_message} </span> </p> </body> </html>
(Please note that this problem and its solution came about three years later than the write-ups above, so the accompanying illustration is unrelated to any seen earlier on this page.)
When the Tomcat output says it can't find the WAR, to wit:
[2021-05-05 05:54:14,833] Artifact jersey:war exploded: Error during artifact deployment. See server log for details. [2021-05-05 05:54:14,834] Artifact jersey:war exploded: com.intellij.javaee.oss.admin.jmx.JmxAdminException: \ com.intellij.execution.ExecutionException: out/artifacts/jersey_war_exploded not found for the web module.
Originally, the Output directory: setting for Project Structure → Artifacts was "out/artifacts/jersey_war_exploded" based on Project Structure → Project → Project compiler output: defaulting to "out" (which I don't like and tend to ignore).
The solution, given to me by JetBrains support, is to place a full path in Project Structure → Artifacts → Output directory: when you create that:
Now, I don't like that path, as I say, so I'm going to use "/home/russ/dev/jersey/target/jersey_war_exploded" instead.
russ@tirion ~/dev/jersey $ find . -name jersey_war_exploded ./target/jersey_war_exploded
Next, the name of the field to configure is Output directory:. Consequently, I'm not going to give the path all the way down to the artifact name, which IntelliJ IDEA seems to ignore. So, my final path is "/home/russ/dev/jersey/target" and, in the end, I get a successful deployment:
... 06-May-2021 06:55:15.713 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"] 06-May-2021 06:55:15.726 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [32] milliseconds Connected to server [2021-05-06 06:55:15,970] Artifact jersey:war exploded: Artifact is being deployed, please wait... [2021-05-06 06:55:16,333] Artifact jersey:war exploded: Artifact is deployed successfully [2021-05-06 06:55:16,334] Artifact jersey:war exploded: Deploy took 364 milliseconds 06-May-2021 06:55:25.714 INFO [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web app... 06-May-2021 06:55:25.732 INFO [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web... ...
What if you've got a project that you did not originally create with adequate resources and framework support?
If you erase the .idea subdirectory, then create a new project in IDEA giving it the name of the project you wish to change, you can accomplish the same thing without creating a whole new project only to copy all your code and other resources into it.* For example:
* which is certainly a simpler if more tedious option.
This means, specifically, web.xml on path src/main/resources/webapp/WEB-INF. You can put it elsewhere (but why?). Here's what it looks like in Project Structure → Modules:
You get this by right-clicking your project name at the top of the Project pane on the left in IDEA, then choose Add Framework Support..., click on and check JAX RESTful Web Services, then OK. This add the Web line in the center pane under your project name in the Project Structure → Modules dialog.
At very least, seemingly, the web descriptor looks something like this:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>jersey</display-name> <servlet> <servlet-name>jersey</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jersey</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
If checked, you will see this:
... Connected to server [2021-05-06 11:21:30,669] Artifact jersey:war exploded: Artifact is being deployed, please wait... [2021-05-06 11:21:31,055] Artifact jersey:war exploded: Artifact is deployed successfully [2021-05-06 11:21:31,055] Artifact jersey:war exploded: Deploy took 386 milliseconds 06-May-2021 11:21:40.570 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/host-manager] 06-May-2021 11:21:40.588 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/host-manager] has finished in [17] ms 06-May-2021 11:21:40.588 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/docs] 06-May-2021 11:21:40.595 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/docs] has finished in [6] ms 06-May-2021 11:21:40.595 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/examples] 06-May-2021 11:21:40.672 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/examples] has finished in [77] ms 06-May-2021 11:21:40.672 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/jersey_war] 06-May-2021 11:21:40.823 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/jersey_war] has finished in [151] ms 06-May-2021 11:21:40.823 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/manager] 06-May-2021 11:21:40.836 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/manager] has finished in [13] ms
...which is a lot of stuff you didn't want anyway probably. Uncheck it to see only one application deployed, yours:
... Connected to server [2021-05-06 11:18:13,647] Artifact jersey:war exploded: Artifact is being deployed, please wait... [2021-05-06 11:18:14,009] Artifact jersey:war exploded: Artifact is deployed successfully [2021-05-06 11:18:14,009] Artifact jersey:war exploded: Deploy took 362 milliseconds 06-May-2021 11:18:23.540 INFO [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/manager] 06-May-2021 11:18:23.556 INFO [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/home/russ/dev/apache-tomcat-10.0.5/webapps/manager] has finished in [16] ms
...which is probably all you want.
TLD means "tagged library descriptor." Seeing the following show up when Tomcat launches doesn't mean there's an error. It's just information.
org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. \ Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. \ Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
To avoid seeing this, add the following line to src/main/resources/logging.properties:
org.apache.jasper.servlet.TldScanner.level = SEVERE
Create this file a) if it doesn't exist and even if b) you use log-back as your logger. In my projects, this is often the only line in logging.properties. Any attempt in logback.xml to fix this failed for me.
However, there is a cost to this. If you tolerate the error/warning, then you get to see this including the deployed services package path and the classes found therein:
11-May-2021 15:00:25.462 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [287] milliseconds 11-May-2021 15:00:25.476 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina] 11-May-2021 15:00:25.476 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.45] 11-May-2021 15:00:25.481 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8088"] 11-May-2021 15:00:25.486 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [23] milliseconds Connected to server [2021-05-11 03:00:25,688] Artifact simple-webapp:war: Artifact is being deployed, please wait... 11-May-2021 15:00:25.954 INFO [RMI TCP Connection(2)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs ... 11-May-2021 15:00:25.965 INFO [RMI TCP Connection(2)-127.0.0.1] com.sun.jersey.api.core.PackagesResourceConfig.init Scanning for root resource and \ provider classes in the packages: com.madhawa.services 11-May-2021 15:00:25.976 INFO [RMI TCP Connection(2)-127.0.0.1] com.sun.jersey.api.core.ScanningResourceConfig.logClasses Root resource classes found: class com.madhawa.services.GoodbyeService class com.madhawa.services.HelloService 11-May-2021 15:00:25.976 INFO [RMI TCP Connection(2)-127.0.0.1] com.sun.jersey.api.core.ScanningResourceConfig.init No provider classes found. 11-May-2021 15:00:26.020 INFO [RMI TCP Connection(2)-127.0.0.1] com.sun.jersey.server.impl.application.WebApplicationImpl._initiate Initiating \ 'Jersey: 1.19.4 05/24/2017 03:20 PM' [2021-05-11 03:00:26,266] Artifact simple-webapp:war: Artifact is deployed successfully [2021-05-11 03:00:26,266] Artifact simple-webapp:war: Deploy took 578 milliseconds 11-May-2021 15:00:35.482 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/home... 11-May-2021 15:00:35.496 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/...
Blocking the error/warning, you see this shorter, cleaner output, but no deployed services package path or classnames:
11-May-2021 14:58:19.905 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [272] milliseconds 11-May-2021 14:58:19.919 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina] 11-May-2021 14:58:19.920 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.45] 11-May-2021 14:58:19.925 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8088"] 11-May-2021 14:58:19.936 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [30] milliseconds Connected to server [2021-05-11 02:58:20,131] Artifact simple-webapp:war: Artifact is being deployed, please wait... [2021-05-11 02:58:20,727] Artifact simple-webapp:war: Artifact is deployed successfully [2021-05-11 02:58:20,727] Artifact simple-webapp:war: Deploy took 596 milliseconds 11-May-2021 14:58:29.926 INFO [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/home... 11-May-2021 14:58:29.942 INFO [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/...
Friday, 7 May 2021
I tried this tutorial, How to Create [a] Java Web Project in IntelliJ IDEA, but could not get it working—failing to HTTP status 404 as is often the case. Nothing I did could get it to work.
I discovered that my problem was using Tomcat 10!
It turns out that IntelliJ IDEA doesn't yet work with version 10, but only 9. JetBrains Support know of this now and predict future fixes as they are able to get to it.
Why did I try to use Tomcat 10? I had just finished building my new development host, tirion. As I'm usually lazy and beholden to older versions of software I have just always used (Tomcat 6, 7, etc.), I often decide to turn over a new leaf when I build new, so I went for Tomcat 10.
Some links that might be helpful...
Imports code-style settings such as are created below (in Export current code style) as an XML file that's easily transported. In the illustration to the right, that's russ.xml.
This will create using the current code style Scheme name an XML file containing code-style settings in a directory on your filesystem.