Spring boot and apache spark - container conflict - maven

I am trying to use spring boot 1.1.5 and apache spark 1.0.2 together in project. Look like apache spark uses Jetty container internally and I have configured spring-boot to use Tomcat container. However application startup fails with some securityException at root cause. If I see full stack trace looks like spring boot trying to initialize "jettyEmbeddedServletContainerFactory" which it shouldn't in first place. It probably picks it up from classpath due to jetty presence via spark. If I exclude jetty from spark and run again I don't see same error again but then SparkContext initialization fails due to not finding jetty. How do i tell spring-boot runtime to look for "TomcatEmbeddedServletContainerFactory" instead of jetty one?

I got "java.lang.SecurityException: class "javax.servlet.http.HttpSessionIdListener"'s signer information does not match signer information of other classes in the same package"
To fix this issue I was need to remove all javax.servlet dependencies.
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.10</artifactId>
<version>1.3.1</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish</groupId>
<artifactId>javax.servlet</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet</artifactId>
</exclusion>
</exclusions>
</dependency>

#Joakim Erdfelt, Thanks.
I was just waiting to see if someone is familiar with this situation and if it's just a small configuration change. As it turns out it is! #Configuration
#EnableAutoConfiguration(exclude={EmbeddedServletContainerFactory.class})
public class MyConfiguration { }
I defined my own "EmbeddedServletContainerFactory" bean as a "org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContaine‌​rFactory" and it started working as I expected.

Related

Correct the classpath of your application so that it contains a single, compatible version of org.elasticsearch.common.logging.Loggers

I'm getting following error while running my Spring boot app, I'm new to Spring boot and elastic search, please help to solve this issue.And attached my pom dependencies below.
Thanks in advance,
*************************** APPLICATION FAILED TO START ***************************
Description:
An attempt was made to call the method org.elasticsearch.common.logging.Loggers.getLogger(Ljava/lang/String;)Lorg/apache/logging/log4j/Logger; but it does not exist. Its class, org.elasticsearch.common.logging.Loggers, is available from the following locations:
jar:file:/C:/Users/Sudhakar/.m2/repository/org/elasticsearch/elasticsearch/6.6.2/elasticsearch-6.6.2.jar!/org/elasticsearch/common/logging/Loggers.class
It was loaded from the following location:
file:/C:/Users/Sudhakar/.m2/repository/org/elasticsearch/elasticsearch/6.6.2/elasticsearch-6.6.2.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.elasticsearch.common.logging.Loggers
Process finished with exit code 1
Maven dependencies:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.11.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.24</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.6.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.6.2</version>
</dependency>
Spring Boot uses Elasticsearch 6.4 by default. By using 6.6.2 as the versions for two Elasticsearch modules you will have ended up with a mixture of the two versions. You should remove the <version> configuration in your pom. If you are able to use Spring Boot’s default version there’s nothing more to do. If you need to use 6.6.2 you should add an entry in your pom’s <properties>:
<elasticsearch.version>6.6.2</elasticsearch.version>

Spring boot failing to start with Spring Cloud AWS Core dependency

I am writing a spring boot app that accesses stuff from an s3 bucket, but I get a NoClassDefFoundError when I use the starter spring-cloud-starter-aws dependency from the spring initializer.
Am I missing some other dependency here?
Below are my dependencies.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</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>
</dependencies>
I also defined the dependencyManagement block for spring-cloud-dependencies and use Edgware.SR1 as my spring-cloud-version.
My app fails with the following error when starting up.
2018-01-24 12:20:25.642 INFO 1980 --- [ main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-01-24 12:20:25.666 ERROR 1980 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.art.productattribution.consumerintegration.ConsumerIntegrationApplication]; nested exception is java.lang.NoClassDefFoundError: com/amazonaws/AmazonClientException
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:616) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
Not sure what am I missing here? Please let me know if you need any more details with this. The version of spring boot I am using is 1.5.9.RELEASE
The correct dependency is the spring-cloud-aws-context. Add the following in your pom file (version 1.2.2 as of Nov 22, 2017):
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-aws-context -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-aws-context</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
Below are the Spring Cloud AWS modules:
Spring Cloud AWS Core is the core module of Spring Cloud AWS providing basic services for security and configuration setup. Developers will not use this module directly but rather through other modules. The core module provides support for cloud based environment configurations providing direct access to the instance based EC2 metadata and the overall application stack specific CloudFormation metadata.
Spring Cloud AWS Context delivers access to the Simple Storage Service via the Spring resource loader abstraction. Moreover developers can send e-mails using the Simple E-Mail Service and the Spring mail abstraction. Further the developers can introduce declarative caching using the Spring caching support and the ElastiCache caching service.
Spring Cloud AWS JDBC provides automatic datasource lookup and configuration for the Relational Database Service which can be used with JDBC or any other support data access technology by Spring.
Spring Cloud AWS Messaging enables developers to receive and send messages with the Simple Queueing Service for point-to-point communication. Publish-subscribe messaging is supported with the integration of the Simple Notification Service.
Ref: http://cloud.spring.io/spring-cloud-aws/spring-cloud-aws.html#_using_amazon_web_services
It seems com.amazonaws.AmazonClientException is not found in the classpath. I think you can add the following dependency in your POM.xml file to solve this issue.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-aws-core</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
You need to include dependency mentioned by #alltej. Also you need to add below property in application.properties file if you are running on local.
cloud.aws.stack.auto=false

Glassfish incremental deployment failes when including Selenium

I have a Java EE project which is meant to run on Glassfish 4.1. I want to use Selenium to collect information from some web pages, i.e. I need to include Selenium in the deployment (not just for tests).
I am using Eclipse IDE and have previously utilized the incremental deployment function in Eclipse to automatically deploy all saved changes to the project. But when I included (with Maven) the dependencies for Selenium incremental deployment stopped working. The project can still be deployed to Glassfish but I have to restart Glassfish between every change. I get the following error in Eclipse:
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.RuntimeException: com.sun.faces.config.ConfigurationException: java.util.concurrent.ExecutionException: com.sun.faces.config.ConfigurationException: Unable to parse document 'bundle://136.0:1/com/sun/faces/jsf-ri-runtime.xml': DTD factory class org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl does not extend from DTDDVFactory.. Please see server.log for more details.
org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl is included with Selenium as a transitive dependency (xerces:xercesImpl:2.11.0).
Here are my Maven dependencies:
<dependency>
<groupId>org.jboss.arquillian.selenium</groupId>
<artifactId>selenium-bom</artifactId>
<version>2.44.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-htmlunit-driver</artifactId>
</dependency>
I hope there is a solution to this but after reading Jens Schauder's response in Dealing with "Xerces hell" in Java/Maven? I'm afraid there might not be. Anyone?
I currently can't reproduce the issue with a simple project, did you make sure that you don't have any other dependencies which are importing another version of xercesImpl?
You can try to place the xercesImpl-2.11.0.jar and the transitive dependency xml-apis-1.4.01.jar in the lib folder of your Glassfish domain and exclude it from your dependencies like this:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-htmlunit-driver</artifactId>
<version>2.44.0</version>
<exclusions>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>
See also:
org.apache.xerces.impl.dv.DVFactoryException: DTD factory class org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl does not extend from DTDDVFactory
Xerces error: org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl

jetty-maven-plugin and loadTimeWeaver

can't seem to have my spring webapp working with jetty-maven pluging
i always get
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [org.eclipse.jetty.webapp.WebAppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
though i have:
set MAVEN_OPTS to javaagent:/Users/blabla/.m2/repository/org/springframework/spring-instrument/3.1.3.RELEASE/spring-instrument-3.1.3.RELEASE.jar
set JAVA_OPTIONS to the same thing
added dep to spring-instrument and spring-aspects
added jvmArgs with -javaagent:.... to jetty-maven-plugin configuration
Probably you are missing few jars aspectjweaver aspectjrt spring-instrument
Additionally you may want to try explicitly defining the bean loadTimeWeaver in applicationcontext.xml file.
<property name="loadTimeWeaver">
<bean id="instrumentationLoadTimeWeaver" class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
When launching Jetty from Maven (using mvn jetty:run), Jetty will run in the same JVM as maven does, so you'll need to pass any options using MAVEN_OPTS.
(Be sure to include the minus sign before javaagent, as I didn't see that in your snippet).
export MAVEN_OPTS=-javaagent:org.springframework.instrument-3.0.5.RELEASE.jar
A complete example of load time weaving in jetty using Maven can be found on Github.
https://github.com/zzantozz/testbed/tree/master/spring-aspectj-load-time-weaving-in-jetty
Without more details about your pom.xml file... it's not easy. But one common issue with jetty plugin are the dependencies.
One rule that always worked for me is to put all dependencies of your war with scope provided as direct dependencies of the maven-jetty-plugin.
I suggest you to put spring-instrument and spring-aspects as direct dependencies of the maven-jetty-plugin too.
According my understanding:
set MAVEN_OPTS to javaagent:/Users/blabla/.m2/repository/org/springframework/spring-instrument/3.1.3.RELEASE/spring-instrument-3.1.3.RELEASE.jar
is the correct way to pass jvm args to the jetty JVM (since jetty run in the same JVM as maven)
I've had same issue I use load time weaving in spring. How can i set class loader in jetty?. I've resolved it by adding a "-Xbootclasspath/a:[path to jar]" as JvmArgs param.
Now it's looks like
<extraJvmArgs>-Xmx4g -XX:MaxPermSize=512m -javaagent:C:\Users\auldanov\.m2\repository\org\springframework\spring-instrument\3.1.4.RELEASE\spring-instrument-3.1.4.RELEASE.jar -Xbootclasspath/a:C:\Users\auldanov\.m2\repository\org\springframework\spring-instrument\3.1.4.RELEASE\spring-instrument-3.1.4.RELEASE.jar</extraJvmArgs>
I finally made it work following the example from ddewaele. So apart from doing
set MAVEN_OPTS to
javaagent:/Users/blabla/.m2/repository/org/springframework/spring-instrument/3.1.3.RELEASE/spring-instrument-3.1.3.RELEASE.jar
You have to check the dependencies you have added. I was missing spring-tx. You need to have these dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<!-- Following dependencies are required because of spring-aspects -->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
Otherwise you get that non-intuitive error
Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
NOTE: You can use the spring version you want. I am using 3.2.5 for everything.
Want to warn everybody! This problem is very unclear.
Don't include this dependency to your project or include with provided scope.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>${thirdparty.spring.version}</version>
</dependency>
Otherwise agent class InstrumentationSavingAgent will load twice (first when loading agent, second while linking libraries) and spring will use second Class instance without injected Instrumentation

Spring + Hibernate + Tomcat Dependency problems

when I run tomcat and the war is deployed I get :
NoClassDefFoundError : org/apache/commons/collections/map/LRUMap
Invocation of init method failed; nested exception is
java.lang.NoClassDefFoundError:
org/apache/commons/collections/map/LRUMap
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
~[spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE]
What is strange is that I got the commons-collections-2.1.jar (I even tried 3.1) in my WEB-INF lib folder.
Edit :
I did copy the commons-collections from WEB-INF/lib to Tomcat lib and it seems to work. However I won't be able to do that on the production server, why isn't it taking my WEB-INF/lib version ?
Ok so I did put version 3.2.1 of commons-collections and the error disappeared. I unfortunately still don't know which library is depending on this version. Even mvn dependency:tree didn't help ...
I had this exception when I was with xdoclet on dependencies.
If you are with this dependency, just exclude it.
I have the same probleme, maybe it's too late to approve the answer but it's still benefitial for people who will have this problem in the futur.
So I exclude commons-collections from net.sf.jasperreports, after that the tomcat runs perfectly whithout any problem.
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>4.1.1</version>
<type>jar</type>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>commons-collections</artifactId>
<groupId>commons-collections</groupId>
</exclusion>
</exclusions>
</dependency>

Resources