I'm facing weird issues when I'm trying to run a spring boot application packaged as a fat jar.
The application works perfectly with Eclipse and with mvn spring-boot:run but when I use java -jar myjar the hibernate entities are not mapped.
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Entity is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:169) ~[hibernate-core-5.2.17.Final.jar!/:5.2.17.Final]
I know that mvn spring-boot:run is different because it changes the classpath but is there a way to run it with verbose so I can see what the classpath is so that I can use java -jar with something similar?
When I print System.getProperty("java.class.path");
I get the following
Classpath:/usr/local/apache-maven/boot/plexus-classworlds-2.5.2.jar
and when I run it from java -jar myJar.jar, I get myJar.jar so that's probably why it's not working.
Here are the pom files :
Api (containing the main class)
<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.foo</groupId>
<artifactId>api</artifactId>
<version>0.0.2-SNAPSHOT</version>
<packaging>jar</packaging>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>service</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jersey2-jaxrs</artifactId>
<version>1.5.13</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>jar-with-all-dependencies</classifier>
<mainClass>
${main-class-path}
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Service (containing the hibernate logic)
<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.foo</groupId>
<artifactId>service</artifactId>
<version>0.0.2-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org-springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org-springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${org-springframework-data.version}</version>
</dependency>
<dependency>
<groupId>org.threeten</groupId>
<artifactId>threetenbp</artifactId>
<version>1.3.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org-springframework.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey-media-json-jackson.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate-core.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>${apt-maven-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/apt</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Here's the main class
#SpringBootApplication
#ComponentScan("com.foo")
public class Application extends SpringBootServletInitializer {
private static final Logger LOG = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
if (!argurmentsValid(args)) {
return;
}
final SpringApplication app = new SpringApplication(Application.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
}
Here's the configuration inside the api
#Configuration
#ApplicationPath("/api")
public class ApiConfiguration extends ResourceConfig {
public static final String CONFIG_FILE_NAME = "api.properties";
public ApiConfiguration() {
register(com.foo.api.v1.controllers.aController.class);
}
}
Here's the configuration inside the service library
#Configuration
#ComponentScan("com.foo.service")
#EnableTransactionManagement
public class ServiceConfiguration {
#Bean
public PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor() {
return new PersistenceAnnotationBeanPostProcessor();
}
#Bean
public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean () {
return new LocalContainerEntityManagerFactoryBean();
}
#Bean
public JpaTransactionManager jpaTransactionManager() {
return new JpaTransactionManager();
}
}
and I have regular hibernate entities inside com.foo.service.
I package the jar with mvn clean install then I run it with java -jar jar-with-all-dependencies.jar
I would need to know some details to be able to help you:
1- How did you package to fat jar?
2- How do you run it?
Springboot cannot be packaged like any other application in a fat jar, like you mentionned, it changes the classpath to be able to use springboot auto-config correctly.
I have recently created a fatjar for springboot app and it works well, but I had to use a repackaging gradle plugin to reassemble the jar correctly. The plugin was made by spring and you probably have the same with maven.
Have you looked here?: https://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins-maven-plugin.html
ALSO
Remember that Eclipse do some classpath magic that gets the job done even if you misconfigured your app.
Where did you specify the EntityScan path? The problem could be spring don't scan the package
Did you forgot to pass parameters to java -jar like spring.profiles.active ?
For fatJar you need:
Special springboot packaging (use plugin)
specifiy main class (you have done that)
Pass required system parameters (profiles, etc.)
Regarding the last point, I have noticed that springboot packaging didn't consider my -D parameters when running using java -jar, I had to use the JavaExec gradle plugin.
Related
I am trying to add the ModelMapper dependency via pom.xml, however, when I try create a new instance of modelMapper it doesn't recognize the dependency and instead tries to import modelMapper from Swagger. I have tried adding it manually and still I get the same problem.
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- PARENT -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.12</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com</groupId>
<artifactId>golden.scent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>something</name>
<description>Demo project for Spring Boot</description>
<!-- PROPERTIES -->
<properties>
<java.version>11</java.version>
</properties>
<!-- DEPENDENCIES -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.8</version>
</dependency>
</dependencies>
<!-- BUILD -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Configuration
import springfox.documentation.swagger2.mappers.ModelMapper;
#Configuration
public class Config {
#Bean
public ModelMapper modelMapper(){
return new ModelMapper()
}
}
Tried using the invalidate cache/restart which usually solves the problem. not this time.
I am trying to use DTO beans and do not want to write a mapper manually.
I have tried looking for solutions but could not find one yet.
Thanks
Change your class to the following:
import org.modelmapper.ModelMapper;
#Configuration
public class Config {
#Bean
public ModelMapper modelMapper(){
return new ModelMapper();
}
}
If with this you can't compile your code, you might need to delete org/modelmapper folder in the .m2 folder in your machine and reload your maven dependencies again.
Try nuking your .m2 folder, and then pull dependencies again. I usually do it like this: delete everything from .m/repo, I go to intellij and add space in pom.xml and delete it so it offers me to pull changes that were made in pom.xml
If that does not help, you can always run from your terminal
mvn clean - clear dependencies so you get something like a clean slate
mvn install - initiates the pulling of dependencies again
I am using Swagger-UI and Codegen to generate my APIs and then I am using Spring Boot and Hibernate in my application.
When I build my application and run via Maven command mvn spring-boot:run, my application runs and Swagger UI is displayed. But when I create the WAR file and deploy it to Tomcat server, I am not able to access the application. I do not see any errors in Catalina logs. Any advice on what could be going wrong?
pom.xml:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.datadivers</groupId>
<artifactId>swagger-spring</artifactId>
<packaging>war</packaging>
<name>swagger-spring</name>
<version>1.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
</parent>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<springfox-version>2.9.2</springfox-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--SpringFox dependencies -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>com.github.joschi.jackson</groupId>
<artifactId>jackson-datatype-threetenbp</artifactId>
<version>2.6.4</version>
</dependency>
<!-- Bean Validation API support -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<finalName>bankingapi</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.5.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Spring Boot application:
imports...
#SpringBootApplication
#EnableSwagger2
#EnableJpaRepositories(basePackages = "com.datadivers.repository")
#EntityScan(basePackages = "com.datadivers.model")
#ComponentScan(basePackages = { "io.swagger", "io.swagger.configuration", "com.datadivers.api", "com.datadivers.service"})
public class Swagger2SpringBoot extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Swagger2SpringBoot.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Swagger2SpringBoot.class);
}
}
The suggestion from #PiotrP.Karwasz worked for me. Hence submitting this as the answer to my problem. Thank you for the help.
Spring 5 requires a Java EE 8 server (it provides a
javax.servlet.ServletContainerInitializer), while Tomcat 10 is a
Jakarta EE 9 server (it searches for a
jakarta.servlet.ServletContainerInitializer): see this question.
Downgrade to Tomcat 9.0 and it should work.
In Intellij idea
in project structure, you can create artifacts
pay attention to output directory this path must be excluded in Module section
now you can add war file to Deployment Section in Configuration Section
if you have security checked the access when input url swagger in to browser
Try this guideline https://www.baeldung.com/spring-boot-war-tomcat-deploy#creating-a-spring-boot-war
add a Tomcat dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
and add SpringBootServletInitializer
like in example
#SpringBootApplication
public class SpringBootTomcatApplication extends SpringBootServletInitializer {
}
I am trying to deploy a GAE SpringBoot application on GCP but no luck.
Getting Below Error:
Uncaught exception from servlet
java.lang.RuntimeException: javax.servlet.ServletException: Not running on Jetty, JSR-356 support unavailable at org.eclipse.jetty.annotations.ServletContainerInitializersStarter.doStart(ServletContainerInitializersStarter.java:68) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at
org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:330)
POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
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.gcptest</groupId>
<artifactId>gcptest-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- Excluded for GCP Conflict, as gcp runs on jetty -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.13</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<!-- Dependency for GCP -->
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>1.9.48</version>
</dependency>
<dependency>
<groupId>com.google.cloud.sql</groupId>
<artifactId>mysql-socket-factory-connector-j-6</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-storage</artifactId>
<version>1.22.0</version>
</dependency>
<dependency>
<groupId>com.google.appengine.tools</groupId>
<artifactId>appengine-gcs-client</artifactId>
<version>0.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.3.1</version>
</plugingcptest
</plugins>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<includes>
<include>*.properties</include>
<include>log4j2.json</include>
</includes>
</resource>
</resources>
</build>
</project>
You must convert your app to App Engine config. If you are using GOOGLE APP ENGINE standard, follow these steps:
Use the WAR packaging
You must use WAR packaging to deploy into Google App Engine Standard.
If you generate a Spring Boot project from start.spring.io, make sure you switch to the full version view of the initializer site, and select WAR packaging.
If you have an existing JAR packaging project, you can convert it into a WAR project by:
In pom.xml, change <packaging>jar</packaging> to <packaging>war</packaging>
Create a new SpringBootServletInitializer implementation:
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(YourApplication.class);
}
}
Remove Tomcat Starter
Google App Engine Standard deploys your WAR into a Jetty server. Spring Boot's starter includes Tomcat by default. This will introduce conflicts. Exclude Tomcat dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
Do not include the Jetty dependencies. But you must include Servlet API dependency:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
Add App Engine Standard Plugin
In the pom.xml, add the App Engine Standard plugin:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.3.1</version>
</plugin>
This plugin is used to run local development server as well as deploying the application into Google App Engine.
Add App Engine Configuration
Add a src/main/webapp/WEB-INF/appengine-web.xml:
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<version>1</version>
<threadsafe>true</threadsafe>
<runtime>java8</runtime>
</appengine-web-app>
This configure is required for applications running in Google App Engine.
Exclude JUL to SLF4J Bridge
Spring Boot's default logging bridge conflicts with Jetty's logging system. To be able to capture the Spring Boot startup logs, you need to exclude org.slf4j:jul-to-slf4j dependency. The easiest way to do this is to set the dependency scope to provided, so that it won't be included in the WAR file:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
Out of memory errors
With Spring Boot >= 1.5.6, you may run into out of memory errors on startup. Please follow these instructions to work around this issue:
Inside src/main/resources, adding a logging.properties file with:
.level = INFO
Inside src/main/webapp/WEB-INF/appengine-web.xml, add a config that points to the new logging.properties file.
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties"/>
</system-properties>
Actually I am trying to get the topic in cloud pub/sub. I have written the code with restful web services when I send the request URL to get the topic i am getting above error. After some lookup,it seams like versions conflict of pub/sub 0.17 version and guava 19.o version but I excluded guava 19 version and added 18 version but same exception coming again and again. However I tried with all guava version but no use same error is coming. Please guide me how to solve and why it is coming.
I am going to attach my code here..
Thanks..
My code:
#Path("/topic")
public class PubSubServices
{
#Path("/gettopic")
#GET
#Produces({ MediaType.TEXT_HTML})
public Response getTopic() throws Exception {
String projectid="My-ProjectID";
String topicname="my-new-topic";
System.out.println("Project name is:"+projectid+" new topic name is:"+topicname);
try
{
TopicAdminClient topicAdminClient topicAdminClient=TopicAdminClient.create();
TopicName topicName = TopicName.create(projectid, topicname);
Topic topic = topicAdminClient.getTopic(topicName);
} catch(Exception e)
{
e.printStackTrace();
}
return Response.status(200).entity(topic.getName();).build();
}
Pom.xml:
<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>PubSub</groupId>
<artifactId>PubSub</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-pubsub</artifactId>
<version>0.17.2-alpha</version>
<exclusions>
<exclusion>
<artifactId>com.google</artifactId>
<groupId>guava</groupId>
</exclusion>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.22.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.17</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.17</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.17</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.17</version>
</dependency>
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
</dependencies>
<build>
<finalName>CloudSubPub1</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
i created war file and i uploaded in glass fish server. when i send request error coming.. seams like the Guava-18 is being overwrite by an older version at runtime, and Guava-18 only works during compile task.
With Main Method It is working gud(Test with main method)
Code:
package com.agro.pubsub.services;
import com.google.cloud.pubsub.spi.v1.TopicAdminClient;
import com.google.pubsub.v1.Topic;
import com.google.pubsub.v1.TopicName;
public class Test {
public static void main(String args[]) throws Exception
{
try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
TopicName topicName = TopicName.create("My-project-Id", "my-new-topic123");
Topic topic = topicAdminClient.getTopic(topicName);
System.out.println(""+topic.getName());
}
}
}
Pom.xml:
<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>PubSub</groupId>
<artifactId>PubSub</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-pubsub</artifactId>
<version>0.17.2-alpha</version>
</dependencies>
</project>
Problem is that when I write code with restful web services with jersey I am getting above error, I am not able find solution.
Any solution for this please?
I got solution to it. I copied guava 19 version into glass fish modules folder
so it means i am overriding guava with my guava version
SOLVED: I updated the Guava dependency to latest version and it solved the issue
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>latest</version>
</dependency>
After running GreetingServerTest.java tests I am getting below given errors. I am using grpc 1.1.0-SNAPSHOT libraries and trying to implement basic Helloword example of grpc given in there git repo. Can anybody please suggest which libraries I am missing or there's anything else I need to do.
java.lang.NoSuchMethodError: io.netty.util.AttributeKey.valueOf(Ljava/lang/Class;Ljava/lang/String;)Lio/netty/util/AttributeKey;
at io.grpc.netty.Utils.<clinit>(Utils.java:87)
at io.grpc.netty.NettyServer.allocateSharedGroups(NettyServer.java:187)
at io.grpc.netty.NettyServer.start(NettyServer.java:116)
at io.grpc.internal.ServerImpl.start(ServerImpl.java:156)
at io.grpc.internal.ServerImpl.start(ServerImpl.java:83)
at com.xyz.communication.datacollection.GrpcServerTest.test(GrpcServerTest.java:23)
pom.xml
<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>org.springframework.samples</groupId>
<artifactId>InternodeCommunication</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Spring -->
<spring-framework.version>4.3.1.RELEASE</spring-framework.version>
<!-- Logging -->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
<!-- Kundera JPA -->
<kundera-version>3.4</kundera-version>
<!-- Hibernate jpa -->
<hibernate.version>4.2.1.Final</hibernate.version>
<!-- Test -->
<junit.version>4.12</junit.version>
<grpc.version>1.1.0-SNAPSHOT</grpc.version>
<!-- Generic properties -->
</properties>
<dependencies>
<!-- Spring and Transactions -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- kafka -->
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka_2.10 -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka_2.10</artifactId>
<version>0.10.0.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.xyz</groupId>
<artifactId>Common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.5.Final</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.grpc/grpc-all -->
<!-- https://mvnrepository.com/artifact/io.netty/netty-codec -->
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<!-- Test Artifacts -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>com.xyz</groupId>
<artifactId>Common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.4.1.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<!-- The version of protoc must match protobuf-java. If you don't depend
on protobuf-java directly, you will be transitively depending on the protobuf-java
version that grpc depends on. -->
<protocArtifact>com.google.protobuf:protoc:3.0.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.1.0-SNAPSHOT:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
hello_world.proto file
syntax = "proto3";
option java_multiple_files = true;
package com.xyz.communication.example;
message HelloRequest {
string name = 1;
}
message HelloResponse {
string greeting = 1;
}
service GreetingService {
rpc greeting(HelloRequest) returns (HelloResponse);
}
GreetingServerTest.java
#ContextConfiguration("/communication-test-beans.xml")
#RunWith(SpringJUnit4ClassRunner.class)
public class GrpcServerTest {
#Test
public void test() throws IOException, InterruptedException {
io.grpc.Server server = ServerBuilder.forPort(8080).addService(new GrpcServerImpl().bindService()).build();
server.start();
server.awaitTermination();
}
}
class GrpcServerImpl extends GreetingServiceGrpc.GreetingServiceImplBase {
#Override
public void greeting(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {
HelloResponse response = HelloResponse.newBuilder().setGreeting("Hello " + request.getName()).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
#Override
public ServerServiceDefinition bindService() {
return super.bindService();
}
}
There could be multiple versions of netty jar in you class path during runtime. Use following command to check dependency tree.
mvn dependency:tree -Dverbose
Or your container provides the netty jar might be clashing with the version of jar you packaging with your application.
Here is what worked for me. I needed to shade io.netty and com.google.
<relocation>
<pattern>io.netty</pattern>
<shadedPattern>myshade.io.netty</shadedPattern>
</relocation>
<relocation>
<pattern>com.google</pattern>
<shadedPattern>myshade.com.google</shadedPattern>
</relocation>