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

MetFragRest JAR file fails to run #96

Open
jkuan1 opened this issue May 10, 2022 · 11 comments
Open

MetFragRest JAR file fails to run #96

jkuan1 opened this issue May 10, 2022 · 11 comments

Comments

@jkuan1
Copy link
Contributor

jkuan1 commented May 10, 2022

Hello!

I have been trying to to use the MetFragRelaunched REST tool and dockerizing it for a project that I am working on. However, I cannot seem to run the compiled JAR file to run at all.

Generally, before I dockerize anything, I like to make sure everything works locally. In the project directory, I run the following commands:

## This command successfully creates a MetFragRest-2.4.8.jar file in MetFragRest/target
mvn clean install -pl MetFragRest -am -DskipTests

## Attempt to run the newly created jar file
java -Dserver.port=8090 -jar MetFragRest/target/MetFragRest-2.4.8.jar

The system specs are:

macOS 11.6.5 (intel processor)
openjdk version "17.0.1" 2021-10-19
apache-maven-3.8.5

Unfortunately, this creates the following output:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.7.RELEASE)
2022-05-10 11:50:17.244  INFO 40430 --- [           main] d.i.metfragrest.MetFragRestController    : Starting MetFragRestController on Taos-MacBook-Pro.local with PID 40430 (/Users/justinkuan/Desktop/Justin/HairExposomeDB/MetFragRelaunched/MetFragRest/target/MetFragRest-2.4.8.jar started by justinkuan in /Users/justinkuan/Desktop/Justin/HairExposomeDB/MetFragRelaunched)
2022-05-10 11:50:17.247  INFO 40430 --- [           main] d.i.metfragrest.MetFragRestController    : No active profile set, falling back to default profiles: default
2022-05-10 11:50:17.302  INFO 40430 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@64bf3bbf: startup date [Tue May 10 11:50:17 PDT 2022]; root of context hierarchy
2022-05-10 11:50:17.462  WARN 40430 --- [           main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
2022-05-10 11:50:17.764 ERROR 40430 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137) ~[spring-boot-1.5.7.RELEASE.jar!/:1.5.7.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537) ~[spring-context-4.3.11.RELEASE.jar!/:4.3.11.RELEASE]
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.7.RELEASE.jar!/:1.5.7.RELEASE]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) ~[spring-boot-1.5.7.RELEASE.jar!/:1.5.7.RELEASE]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) ~[spring-boot-1.5.7.RELEASE.jar!/:1.5.7.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-1.5.7.RELEASE.jar!/:1.5.7.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) ~[spring-boot-1.5.7.RELEASE.jar!/:1.5.7.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) ~[spring-boot-1.5.7.RELEASE.jar!/:1.5.7.RELEASE]
        at de.ipbhalle.metfragrest.MetFragRestController.main(MetFragRestController.java:368) ~[classes!/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) ~[MetFragRest-2.4.8.jar:na]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) ~[MetFragRest-2.4.8.jar:na]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) ~[MetFragRest-2.4.8.jar:na]
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) ~[MetFragRest-2.4.8.jar:na]
Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:189) ~[spring-boot-1.5.7.RELEASE.jar!/:1.5.7.RELEASE]
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:162) ~[spring-boot-1.5.7.RELEASE.jar!/:1.5.7.RELEASE]
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134) ~[spring-boot-1.5.7.RELEASE.jar!/:1.5.7.RELEASE]
        ... 16 common frames omitted

Being relatively new to Java, I thought that this may be because of different language versions. As such, I went ahead with trying to dockerize the REST tool with the following Dockerfile:

FROM maven:3-jdk-11 AS builder

COPY . /MetFragRelaunched

RUN mvn -f MetFragRelaunched clean install -pl MetFragRest -am -DskipTests

FROM openjdk:11

COPY --from=builder /MetFragRelaunched/MetFragRest/target/MetFragRest-2.4.8.jar /rest-app.jar

ENTRYPOINT ["java", "-Dserver.port=8090", "-jar", "/rest-app.jar"]

I am using jdk-11 as that appeared to be the version used for the MetFragWeb tool.

I would then build the docker image and run it using this command (Docker 4.5.0):
docker build . -t metfragrest:dev && docker run -p 8090:8090 -it --rm --name metfragrest-test metfragrest:dev

However, the container would fail to run with the same output as above. I am looking for guidance on how to resolve this error and maybe have someone point out whatever mistake I am making because I believe that I am overlooking something but I cannot seem to figure out what. I have tried multiple different Java versions (for both the maven and java containers), but they would also fail. Earlier versions cannot even build the jar file.

Any sort of guidance is appreciated. @sneumann @meier-rene

Many thanks,
Justin

@jkuan1 jkuan1 changed the title MetFragRest compilation fails MetFragRest JAR file fails to run May 10, 2022
@sneumann
Copy link
Member

sneumann commented May 11, 2022

Hi, I can confirm on an entirely different setup:

openjdk 11.0.15 2022-04-19
Apache Maven 3.6.3
Ubuntu 18.04

I tried a different port, and I tried to add a dependency (https://exerror.com/org-springframework-boot-context-embedded-embeddedservletcontainerexception-unable-to-start-embedded-tomcat-servlet-container/#h-solution-2-add-the-tomcat-dependency) to no avail.

I have an inkling that we need to bump some spring dependency versions to 1) make it work, and 2) to get back from ancient to supported dependency versions. Just naively updating the pom.xml to go from 1.5.7.RELEASE to 2.6.7 causes follow-up compiling issues related to org.springframework.hateoas where I then gave up for now. Suggestions ? Yours, Steffen.

@jkuan1
Copy link
Contributor Author

jkuan1 commented May 11, 2022

I tried that as well. I think the issue with upgrading hateoas alongside spring boot is that later versions of hateoas moved classes around. This means that imports and code will have to change too and I'm not sure how deep that rabbit hole is. I was hoping that using docker and building + running the JAR file on older versions of Java can bypass the dependency issue but so far I have had no luck with Java versions below 11.

Without any new suggestions, it may be time for me to earnestly dive deep into the rabbit hole haha.

@jkuan1
Copy link
Contributor Author

jkuan1 commented May 11, 2022

I take back what I said! The above Dockerfile and docker command works! It wasn't working earlier because I forgot to uncomment out some code I was reviewing.
Unfortunately, while the JAR file is running, I can't seem to communicate with port 8090 where the JAR file should be running. Talking to port 8080 of the docker container pulls up the default webpage for the tomcat server. Some more tinkering is needed and I will provide updates when I can.

@sneumann
Copy link
Member

Hi, great progress! A quick guess is that the REST is residing somewhere at localhost:8090/MetFragREST , but I couldn't quickly locate where the URL base is located. Yours, Steffen

@meier-rene
Copy link
Contributor

Hi, maybe I can help here. According to my limited spring knowledge, this code tells us the location of the endpoint:


Hope that helps a bit.
Yours, Rene

@jkuan1
Copy link
Contributor Author

jkuan1 commented May 12, 2022

I looked around in the created Docker container and it appears that the reason it worked was because it failed to copy the JAR file into the image (I made a manual mistake).

As such, when I did successfully run the JAR file, the same old error popped up (back to square one). I will try experimenting with using a tomee base image instead of a openjdk one.

Thank you for the input! I will be sure to keep it in mind when I finally clear this first hurdle of getting the JAR to run.

@jkuan1
Copy link
Contributor Author

jkuan1 commented May 13, 2022

Been playing around with the pom.xml file to no avail. Some clues I got from digging round seem to suggest that a tomcat dependency (tomcat-embed-core 8.5.20) is not starting because of this following error:
Caused by: java.lang.NoSuchMethodError: 'java.lang.String javax.servlet.ServletContext.getVirtualServerName()'.

Googling this errors suggests that we need version 3.1.0 of javax.servlet:servlet-api but we are currently using 2.3.0
I have tried editing the pom.xml by adding

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

To the dependencies section of the dependencyManager section (full pom below) but now the compilation fails. As someone that is relatively new to Java projects, am I missing something?

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>de.ipbhalle.metfrag</groupId>
		<artifactId>MetFrag</artifactId>
		<version>2.4.8</version>
	</parent>
	<groupId>de.ipbhalle.metfrag.metfragrest</groupId>
	<artifactId>MetFragRest</artifactId>
	<packaging>jar</packaging>
	<name>MetFragRest</name>
	<url>http://maven.apache.org</url>

	<dependencies>
		<dependency>
			<groupId>de.ipbhalle.metfraglib</groupId>
			<artifactId>MetFragLib</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>io.fabric8</groupId>
			<artifactId>kubernetes-client</artifactId>
			<version>3.1.10</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.hateoas</groupId>
			<artifactId>spring-hateoas</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-api</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
		</dependency>
	</dependencies>
	<dependencyManagement>
		<dependencies>
			<!-- Override Spring Data release train provided by Spring Boot -->
			<dependency>
				<groupId>org.springframework.data</groupId>
				<artifactId>spring-data-releasetrain</artifactId>
				<version>Fowler-SR2</version>
				<scope>import</scope>
				<type>pom</type>
			</dependency>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>1.5.7.RELEASE</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<dependency>
				<groupId>javax.servlet</groupId>
				<artifactId>javax.servlet-api</artifactId>
				<version>3.1.0</version>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>1.5.7.RELEASE</version>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

@jkuan1
Copy link
Contributor Author

jkuan1 commented May 16, 2022

I got a temporary solution! The ChemSpider dependency in MetFragLib requires javax.servlet-api version 2.3.
I have completely removed ChemSpider from MetFragLib and MetFragRest now works.

I cannot seem to find the ChemSpider webservices JAR anywhere (I can't even figure out where Maven pulls the current JAR file from), is there a resource that I can be directed towards to see if I can get a more updated version of the dependency? This is so that I do not have to delete the entire function instead.

TL;DR is that tomcat needs javax.servlet 3.1 but ChemSpider needs javax.servlet 2.3.

Temporary solution is removing ChemSpider entirely from MetFragLib. Given more spare time I will see if I can find a better solution.

@sneumann
Copy link
Member

Awesome ! two comments:

  1. ChemSpider is coming from the rather obscure source https://msbi.ipb-halle.de/~cruttkie/maven2/com/chemspider/www/chemspider_webservices/ (i.e. we are hosting it ourselves, and I don't think we have the sources for it)
  2. ChemSpider and their Token stuff is something a bit hard to maintain. So I am in favor of removing it. Could you get us your temporary solution as PR ?
    Yours,
    Steffen

@jkuan1
Copy link
Contributor Author

jkuan1 commented May 17, 2022

I created a PR of the changes I made to get MetFragRest to work. I see the new issue but only had the time to remove ChemSpider from MetFragLib. If there are issues to the PR, just comment on it in the PR itself and I can see what I can do.

On the other hand, now that MetFragRest runs, I was wondering if the following output is what is intended (This is using the example query in the MetFragRest README):

{
    "name": "process",
    "processId": "java.io.tmpdir12568693853721074997",
    "links": [
        {
            "rel": "self",
            "href": "http://localhost:8090/metfrag/api/v1/process"
        },
        {
            "rel": "status",
            "href": "http://localhost:8090/metfrag/api/v1/status/java.io.tmpdir12568693853721074997"
        },
        {
            "rel": "host",
            "href": "http://localhost:8090/metfrag/api/v1/host/java.io.tmpdir12568693853721074997"
        },
        {
            "rel": "result",
            "href": "http://localhost:8090/metfrag/api/v1/result/java.io.tmpdir12568693853721074997"
        },
        {
            "rel": "resultzip",
            "href": "http://localhost:8090/metfrag/api/v1/resultzip/java.io.tmpdir12568693853721074997"
        }
    ]
}

Are there any ideas on how to retrieve those files mentioned in the JSON (that are in a docker container) from another docker container?

@jkuan1
Copy link
Contributor Author

jkuan1 commented May 17, 2022

In response to my previous question, I now understand the role of HATEOAS in the application. After reading the code, I am supposed to first send the request for processing.
Then I use the returned links after the request is done computing to retrieve the results in the format that I want (such as zip file or csv).

Unfortunately, it appears that the endpoints are not working properly. For example, when I try to check the status, this is the output:

{
    "timestamp": 1652803302105,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "de.ipbhalle.exception.CouldNotReadStatusException",
    "message": "Could not read status for process id 'java.io'",
    "path": "/metfrag/api/v1/status/java.io.tmpdir11114803055545553808"
}

It appears that it thinks the processID is java.io and not java.io.tmpdir11114803055545553808.
Since this is now a new issue, I can start a new discussion on it and close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants