Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClassNotFoundException: com.example.appengine.demo.jettymain.Main #3299

Closed
deepfriedbrain opened this issue Jul 6, 2020 · 7 comments
Closed
Assignees
Labels
api: appengine Issues related to the App Engine Admin API API. priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. type: question Request for information or clarification. Not an issue.

Comments

@deepfriedbrain
Copy link

deepfriedbrain commented Jul 6, 2020

In which file did you encounter the issue?

https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/appengine-java11/helloworld-servlet

Did you change the file? If so, how?

No

Describe the issue

I'm trying to deploy my first GAE Java 11 runtime app. I followed the example in helloworld-servlet and created my own (real) servlet. It works perfectly on my local machine, but when I deploy it, it is not able to find the main class, which comes from appengine-simple-jetty-main. Here's the error:

Error: Could not find or load main class com.example.appengine.demo.jettymain.Main
Caused by: java.lang.ClassNotFoundException: com.example.appengine.demo.jettymain.Main

I've followed every step per the documentation, but it's not working after deployment (works fine on localhost). Am I missing something?

Since simple-jetty-main is a provided dependency, is it supposed to be provided by the runtime? I'm really not clear and found the documentation to be very confusing.

This is my app.yaml:

runtime: java11
entrypoint: 'java -cp "*" com.example.appengine.demo.jettymain.Main <my-app-name>.war'

This is my pom.xml:

<?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>
  <packaging>war</packaging>
  <groupId>com.mycompany.services</groupId>
  <artifactId>my-app-name</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>my-app-name</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <failOnMissingWebXml>false</failOnMissingWebXml>
  </properties>

    <dependencies>
        <dependency>
            <groupId>com.example.appengine.demo</groupId>
            <artifactId>simple-jetty-main</artifactId>
            <version>1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>google-cloud-logging</artifactId>
            <version>1.101.2</version>
        </dependency>

        <dependency>
            <groupId>com.sendgrid</groupId>
            <artifactId>sendgrid-java</artifactId>
            <version>4.6.0</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>my-app-name</finalName>

        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>com.google.cloud.tools</groupId>
                    <artifactId>appengine-maven-plugin</artifactId>
                    <version>2.3.0</version>
                    <configuration>
                        <projectId>GCLOUD_CONFIG</projectId>
                        <version>1</version>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <version>3.1.2</version>
                    <executions>
                    <execution>
                        <id>copy</id>
                        <phase>prepare-package</phase>
                        <goals>
                        <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                        <outputDirectory>
                            ${project.build.directory}/appengine-staging
                        </outputDirectory>
                        </configuration>
                    </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

My directories are sitting parallel to each other (not sure if this is correct):

- appengine-simple-jetty-main
- my-app-name
@gguuss gguuss assigned sgreenberg and unassigned gguuss Jul 6, 2020
@lesv lesv assigned averikitsch and unassigned sgreenberg Jul 6, 2020
@lesv lesv added type: question Request for information or clarification. Not an issue. priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. api: appengine Issues related to the App Engine Admin API API. labels Jul 6, 2020
@lesv
Copy link
Contributor

lesv commented Jul 6, 2020

I do wish things you should change were ALL CAPS in the README.md file.

  1. Make sure you cd simple-jetty-main; mvn install
  2. You should update MY-APP-NAME in the finalName element and artifactId element of your pom.xml
  3. You should update the groupId element in your pom.xml
  4. You should update your app.yaml with the same finalName
runtime: java11
entrypoint: 'java -cp "*" com.example.appengine.demo.jettymain.Main MY-APP-NAME.war'

@deepfriedbrain
Copy link
Author

deepfriedbrain commented Jul 6, 2020

I have updated readme to say documentation.

  1. I'm calling the folder appengine-simple-jetty-main (not simple-jetty-main) per the documentation. I've performed this step. Otherwise, it would not have worked on my local.
  2. my-app-name is not what I'm using in my real files. I didn't want to post the real app name on a public issue.
  3. Similar to point 2, I edited out the real company name before posting the issue.
  4. Same as point 2.

So none of these points apply for my case. What else could be wrong?

@averikitsch
Copy link
Contributor

To troubleshoot this you should try to stage your app for deployment. For the servlet, we have set up the maven-dependency-plugin to do this on mvn package. I do want to note that I usually do this using the appengine-maven-plugin and the goal: mvn clean package appengine:stage. This will create an appengine-staging directory within your target directory. You should check to see if the simple-jetty-main-1.jar (or your equivalent) is in that directory to be deploy along with your war and app.yaml. However, I see that you have these plugins in your <pluginManagement> section. This seems to prevent the plugin from working as intended; therefore try removing the pluginManagement tags.

@deepfriedbrain
Copy link
Author

@averikitsch Removing pluginManagement did the trick! It was added automatically when I created a maven project. Thanks a lot for your help.

While I was waiting for a response yesterday, I also managed to get it working by embedding Jetty directly into my project and uploading a single Uber / Fat JAR.

Are there any pros and cons of using a separate simple-jetty-main artifact versus embedding Jetty directly into the project?

For one, I noticed that yesterday with a single fat JAR file, it was using about 130MB of memory on the server, but today following the helloworld-servlet example, it is at 217MB from the beginning. For now, my application has just one Servlet that handles the form submission for my static website. So the memory usage seems to be on a higher side.

In any case, I'll proceed to close this ticket as my original issue has been addressed. Thanks again.

@averikitsch
Copy link
Contributor

The simple-jetty-main exists because we want users to have insight to the jetty server and have the capabilities of editing the class to fit their needs. If you have time, what was your process for directly embedding jetty into your project?

@deepfriedbrain
Copy link
Author

This is the first time I was using Jetty. I did pretty much what simple-jetty-main does:

  1. Included jetty dependencies in my pom.xml.
  2. Added my own Main class, which was pretty similar to the one in the simple-jetty-main, but I added my own ServletHandler instead of using WebAppContext:
Server server = new Server(port);
ServletHandler handler = new ServletHandler();
server.setHandler(handler);
handler.addServletWithMapping(CommentHandler.class, "/comment-handler");
  1. Back in pom.xml again, I changed the packaging from war to jar.
<packaging>jar</packaging>
  1. Added maven-assembly-plugin to build the Fat Jar.
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <appendAssemblyId>false</appendAssemblyId>
            <archive>
                <manifest>
                    <mainClass>com.mycompany.services.main.Main</mainClass>
                </manifest>
            </archive>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>

        <executions>
            <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
</plugin>
  1. Deployed the JAR to app engine.

@deepfriedbrain
Copy link
Author

deepfriedbrain commented Jul 10, 2020

@averikitsch This is my first GAE Java 11 runtime app. I have 2 observations:

  1. Memory usage is quite high ~220MB for a test application with one servlet.
  2. It takes a really long time (5-8 mins) to deploy. In comparison, my Java 8 runtime app, which is a much bigger in terms of the number of files, deploys in about 30-40secs.

UPDATE:

  1. After removing google-cloud-logging and send-grid, the memory usage came down by 50MB, and 45MB respectively. Now my app is at around 122MB.
  2. Deployment also was much faster ~1:40min.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: appengine Issues related to the App Engine Admin API API. priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. type: question Request for information or clarification. Not an issue.
Projects
None yet
Development

No branches or pull requests

5 participants