Tries to create an web application based on spring boot with web-socket support
Define public static main class annotated with #SpringBootApplication
#SpringBootApplication
public class Facade {
public static void main(String[] argv) throws IOException {
Map<String,Object> contextProperties = new HashMap<>();
contextProperties.put("server.port",p.getProperty("server.port","8091"));
SpringApplication app = new SpringApplication(Facade.class);
app.setDefaultProperties(contextProperties);
app.run(argv);
}
}
Add configuration class
#Configuration
#EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new SocketTextHandler(), "/ws").setAllowedOrigins("*");
}
}
Add handler
#Component
public class SocketTextHandler extends TextWebSocketHandler {
#Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
String payload = message.getPayload();
session.sendMessage(new TextMessage("Hi " + payload + " how may we help you?"));
}
#Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
session.sendMessage(new TextMessage("Connected!"));
}
}
There are maven dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>9.0.31</version>
</dependency>
spring boot version is 2.5.5
When I connect to socket using JavaScript
webSocket = new WebSocket(wsUrl);
I see in app logs
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.socket.server.HandshakeFailureException: Servlet request failed to upgrade to WebSocket: http://127.0.0.1:8091/ws; nested exception is javax.servlet.ServletException: java.lang.reflect.InvocationTargetException] with root cause
java.lang.ClassNotFoundException: org.apache.coyote.http11.upgrade.UpgradeInfo
The tomcat-coyote dependency is in pom.xlm
I used web-sockets in jersey implementation under tomcat9. Now I tries to migrate application to spring-boot, but confused with NoClassDef exception.
Could you please explain or suggest solution for this cause.
Related
I am migrating an application to Spring boot 3.0, but I have a problem with the injection of a ProducerTemplate in one of my services (annotation #Service se Spring Boot).
I was using the Spring Boot starter from Camel
Current Spring Boot version is : 2.7.5
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>3.15.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-rabbitmq-starter</artifactId>
<version>3.15.0</version>
</dependency>
My ProducerTemplate is injected into the constructor of my service that extends RouteBuilder
#Service
public class MyServiceImpl extends RouteBuilder implements MyService {
private final ProducerTemplate producerTemplate;
#Autowired
public MyServiceImpl(ProducerTemplate producerTemplate) {
this.producerTemplate = producerTemplate;
}
At startup, the application crashes with this message :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.mycompany.ServiceImpl required a bean of type 'org.apache.camel.ProducerTemplate' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.apache.camel.ProducerTemplate' in your configuration.
It's not very clear to me how I should take it.
I guess I have to use the dependency
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>3.15.0</version>
</dependency>
instead of
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>3.15.0</version>
</dependency>
But I don't really know how I should instantiate the ProducerTemplate and the CamelContext ?
I tried without really believing something like this :
#Configuration
public class CamelConfig {
#Bean
public CamelContext getCamelContext() throws Exception {
CamelContext context = new DefaultCamelContext();
if (context.isStopped()) context.start();
return context;
}
#Bean
public ProducerTemplate getProducerTemplate() throws Exception
{
final ProducerTemplate template = getCamelContext().createProducerTemplate();
return template;
}
}
#Service
public class MyServiceImpl implements MyService {
private final ProducerTemplate producerTemplate;
private CamelContext context;
#Autowired
public MyServiceImpl(ProducerTemplate producerTemplate, CamelContext context) {
this.producerTemplate = producerTemplate;
this.context = context;
try {
this.context.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from("direct:update-legacy")
.to("bean:updateJdbc");
The app failed with the following error message :
Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: bean://updateJdbc due to: No bean could be found in the registry for: updateJdbc
I created a new sample and slipted the codes into client and server side.
The complete codes can be found here.
There are 3 version of server side.
server None Spring Boot app, using Spring Integration RSocket InboundGateway.
server-boot Reuse Spring RSocket autconfiguration, and created ServerRSocketConnecter through ServerRSocketMessageHanlder.
server-boot-messsagemapping Not use Spring Integration, just use Spring Boot RSocket autconfiguration, and #Controller and #MessageMapping.
There are 2 versions of client.
client, Sending messages using Spring Integration Rocket OutboundGateway.
client-requester Send messages using RSocketRequester, not use Spring Integration at all.
The client and server interaction mode is REQUEST_CHANNEL, and connect server via TCP/localhost:7000.
server
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-rsocket</artifactId>
</dependency>
The application class:
#Configuration
#ComponentScan
#IntegrationComponentScan
#EnableIntegration
public class DemoApplication {
public static void main(String[] args) throws IOException {
try (ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(DemoApplication.class)) {
System.out.println("Press any key to exit.");
System.in.read();
} finally {
System.out.println("Exited.");
}
}
#Bean
public ServerRSocketConnector serverRSocketConnector() {
return new ServerRSocketConnector("localhost", 7000);
}
#Bean
public IntegrationFlow rsocketUpperCaseFlow(ServerRSocketConnector serverRSocketConnector) {
return IntegrationFlows
.from(RSockets.inboundGateway("/uppercase")
.interactionModels(RSocketInteractionModel.requestChannel)
.rsocketConnector(serverRSocketConnector)
)
.<Flux<String>, Flux<String>>transform((flux) -> flux.map(String::toUpperCase))
.get();
}
}
server-boot
Dependencies in pom.xml.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-rsocket</artifactId>
</dependency>
application.properties
spring.rsocket.server.port=7000
spring.rsocket.server.transport=tcp
Application class.
#SpringBootApplication
#EnableIntegration
public class DemoApplication {
public static void main(String[] args) throws IOException {
SpringApplication.run(DemoApplication.class, args);
}
// see PR: https://github.com/spring-projects/spring-boot/pull/18834
#Bean
ServerRSocketMessageHandler serverRSocketMessageHandler(RSocketStrategies rSocketStrategies) {
var handler = new ServerRSocketMessageHandler(true);
handler.setRSocketStrategies(rSocketStrategies);
return handler;
}
#Bean
public ServerRSocketConnector serverRSocketConnector(ServerRSocketMessageHandler serverRSocketMessageHandler) {
return new ServerRSocketConnector(serverRSocketMessageHandler);
}
#Bean
public IntegrationFlow rsocketUpperCaseFlow(ServerRSocketConnector serverRSocketConnector) {
return IntegrationFlows
.from(RSockets.inboundGateway("/uppercase")
.interactionModels(RSocketInteractionModel.requestChannel)
.rsocketConnector(serverRSocketConnector)
)
.<Flux<String>, Flux<String>>transform((flux) -> flux.map(String::toUpperCase))
.get();
}
}
server-boot-messagemapping
Dependencies in pom.xml.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
The application.properties.
spring.rsocket.server.port=7000
spring.rsocket.server.transport=tcp
The applcition class.
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
#Controller
class UpperCaseHandler {
#MessageMapping("/uppercase")
public Flux<String> uppercase(Flux<String> input) {
return input.map(String::toUpperCase);
}
}
client
In the client, the dependencies in the pom.xml is like.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-rsocket</artifactId>
</dependency>
The application class:
#SpringBootApplication
#EnableIntegration
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Bean
public ClientRSocketConnector clientRSocketConnector() {
ClientRSocketConnector clientRSocketConnector = new ClientRSocketConnector("localhost", 7000);
clientRSocketConnector.setAutoStartup(false);
return clientRSocketConnector;
}
#Bean
public IntegrationFlow rsocketUpperCaseRequestFlow(ClientRSocketConnector clientRSocketConnector) {
return IntegrationFlows
.from(Function.class)
.handle(RSockets.outboundGateway("/uppercase")
.interactionModel((message) -> RSocketInteractionModel.requestChannel)
.expectedResponseType("T(java.lang.String)")
.clientRSocketConnector(clientRSocketConnector))
.get();
}
}
#RestController
class HelloController {
#Autowired()
#Lazy
#Qualifier("rsocketUpperCaseRequestFlow.gateway")
private Function<Flux<String>, Flux<String>> rsocketUpperCaseFlowFunction;
#GetMapping(value = "hello", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> uppercase() {
return rsocketUpperCaseFlowFunction.apply(Flux.just("a", "b", "c", "d"));
}
}
When running the client and server application, and try to access the http://localhost:8080/hello by curl.
When using server and server-boot which uses InboundGateway to handle messages, the output looks like this.
curl http://localhost:8080/hello
data:ABCD
When using server-boot-messagemapping, the output is woking as I expected:
data:A
data:B
data:C
data:D
client-requester
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
The application class:
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
#RestController
class HelloController {
Mono<RSocketRequester> requesterMono;
public HelloController(RSocketRequester.Builder builder) {
this.requesterMono = builder.connectTcp("localhost", 7000);
}
#GetMapping(value = "hello", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> uppercase() {
return requesterMono.flatMapMany(
rSocketRequester -> rSocketRequester.route("/uppercase")
.data(Flux.just("a", "b", "c", "d"))
.retrieveFlux(String.class)
);
}
}
When running this client and the 3 servers, and try to access the http://localhost:8080/hello by curl.
When using server and server-boot which uses InboundGateway to handle messages, it throws a class cast exception.
When using server-boot-messagemapping, the output is woking as I expected:
data:A
data:B
data:C
data:D
I do not know where is the problem of the configuration of InboundGateway and OutboundGateway?
Thank you for such a detailed sample!
So, what I see. Both clients (plain RSocketRequester and Spring Integration) work well with plain RSocket server.
To make them working with Spring Integration server you have to do this changes:
The server side:
Add .requestElementType(ResolvableType.forClass(String.class)) into an RSockets.inboundGateway() definition, so it will know to what to convert an incoming payloads.
The client side:
.data(Flux.just("a\n", "b\n", "c\n", "d\n")).
Currently the server side of Spring Integration doesn't treat an incoming Flux as a stream of independent payloads. So, we try to connect all of them into a single value.
The new line delimiter is an indicator that we expect independent values. Spring Messaging on its side does exactly opposite: it checks for multi-value expected type and decode every element in the incoming Flux in its map() instead of an attempt for the whole Publisher decoding.
It's going to be kinda breaking change, but possibly need to consider to fix RSocketInboundGateway logic to be consistent with regular #MessageMapping for RSocket support. Feel free to raise a GH issue!
I have an spring boot app that is exchanging messages over binary websocket. I.e. NO STOMP, AMQP etc. or any other messaging protocol!!! Now I need to mark one of my classes with the Scope of "websocket". Like that befow:
#Service("session")
#Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Session {
...
}
I have read the documentation here that quote:
" WebSocket-scoped beans can be injected into controllers and any
channel interceptors registered on the "clientInboundChannel". "
I would like to emphasis the word "and" in that sentence.
Well i do have a controller, but i do not have any channelInterceptor. I am injecting this as:
#Controller("entryPoint")
public class EntryPoint {
#Autowired
private ApplicationContext applicationContext;
private ApplicationEventPublisher applicationEventPublisher;
#Autowired
private Session session;
...
#PostConstruct
public void init() {
// Invoked after dependencies injected
logger.info("EntryPoint init method i.e. #PostConstruct invoked");
}
...
}
Now the first thig i found to be interesting is that i need the annotation #EnableWebSocketMessageBroker i.e. it seems that #EnableWebSocket is not enough , but then comes the question why. I should be able to define that scope independinglly whether i am using messaging protocol or not. At least that is what i belive.
anyway without it i am getting the error
java.lang.IllegalStateException: No Scope registered for scope name 'websocket'
I said ok, lets create a dummy config file for the message broker which is bringing additional dependencies such as :
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-net</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.13.Final</version>
</dependency>
as a config like
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketMessageBrokerConfig implements WebSocketMessageBrokerConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/testEndPoint");
}
#Override
public void configureClientInboundChannel(ChannelRegistration inboundChannelRegistration) {
}
#Override
public void configureClientOutboundChannel(ChannelRegistration outboundChannelRegistration) {
}
#Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
return true;
}
#Override
public void configureWebSocketTransport(WebSocketTransportRegistration webSocketTransportRegistration) {
webSocketTransportRegistration.setMessageSizeLimit(45678910);
webSocketTransportRegistration.setSendBufferSizeLimit(9101112);
webSocketTransportRegistration.setSendTimeLimit(123456789);
}
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) {
System.out.println("WEB SOCKET ARGUMENT RESOLVER");
}
#Override
public void addReturnValueHandlers(
List<HandlerMethodReturnValueHandler> arg0) {
System.out.println("WEB SOCKET RETURN VALUE HANDLER");
}
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
StompBrokerRelayRegistration stompBrokerRelayRegistration = config.enableStompBrokerRelay(
"/topic/",
"/queue/errors",
"/exchange/amp.direct/testaError/",
"/exchange/amp.direct/testCreateAccount/"
);
stompBrokerRelayRegistration.setRelayHost("127.0.0.6");
stompBrokerRelayRegistration.setRelayPort(61613);
stompBrokerRelayRegistration.setSystemLogin("guest");
stompBrokerRelayRegistration.setSystemPasscode("guest");
stompBrokerRelayRegistration.setAutoStartup(true);
stompBrokerRelayRegistration.setSystemHeartbeatSendInterval(5000);
stompBrokerRelayRegistration.setSystemHeartbeatReceiveInterval(4000);
config.setApplicationDestinationPrefixes("/app");
}
}
which brings the error message:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.serverSyncSession': Scope 'websocket' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound SimpAttributes found. Your code is probably not processing a client message and executing in message-handling methods invoked by the SimpAnnotationMethodMessageHandler?
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:355) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
...
Caused by: java.lang.IllegalStateException: No thread-bound SimpAttributes found. Your code is probably not processing a client message and executing in message-handling methods invoked by the SimpAnnotationMethodMessageHandler?
at org.springframework.messaging.simp.SimpAttributesContextHolder.currentAttributes(SimpAttributesContextHolder.java:82) ~[spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.messaging.simp.SimpSessionScope.get(SimpSessionScope.java:36) ~[spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:340) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
... 45 common frames omitted
While the message is clear i.e. my code is indeed not thread bound and is executed in a messageHandelr just not in the SimpAnnotationMethodMessageHandler, but in a BinaryMessageHandler class that extends BinaryWebSocketHandler. Why should i not be able to place a scope on a bean it is clearlly used by the websockets. Why do we need all annotation #EnableWebSocketMessageBroker at all and all following dependencies?
It is not really clear to me what else do i need to do in order to get my bean with the right scope. Somehow i have the feeling that this will get me again to some messaging dependency that i am really trying to avoid.
My question is does anyone have some hint for me what do I need to do in BinaryMessageHandler in order to tell spring to thread that session bean with the scope "wesocket". Is there a way to achive that without the annotation #EnableWebSocketMessageBroker?
any feedback is appreciated.
I'm trying to set up a project with the stack on title, the JMS that we're using is ActiveMQ. So, here is the configuration that I'm doing:
#SpringBootApplication
public class Application {
private static Logger logger = Logger.getLogger(Application.class);
#Value("${broker.component.name}")
private String brokerComponetName;
#Value("${broker.dead.letter.queue}")
private String brokerDeadLetterQueue;
#Value("${broker.in.queue}")
private String brokerInQueue;
#Value("${broker.out.queue}")
private String brokerOutQueue;
#Value("${broker.url}")
private String brokerUrl;
#Value("${broker.user}")
private String brokerUser;
#Value("${broker.password}")
private String brokerPassword;
public static void main(String[] args) throws Exception {
logger.info("starting loader");
SpringApplication.run(Application.class, args);
}
#Bean
public SpringCamelContext camelContext(ApplicationContext applicationContext) throws Exception {
SpringCamelContext camelContext = new SpringCamelContext(applicationContext);
camelContext.addComponent(brokerComponetName, JmsComponent.jmsComponent(connectionFactory()));
camelContext.addRoutes(new RouteBuilder() {
public void configure() throws ConfigurationException {
errorHandler(deadLetterChannel(brokerDeadLetterQueue)
.onRedelivery(new FailureProcessor())
.useOriginalMessage()
.maximumRedeliveries(5)
.redeliveryDelay(5000)
.retryAttemptedLogLevel(LoggingLevel.INFO));
from(brokerInQueue)
.process(new MessageProcessor())
.to(brokerOutQueue);
}
});
return camelContext;
}
#Bean
public ConnectionFactory connectionFactory() throws ConfigurationException {
System.out.println("BROKER URL: " + brokerUrl);
return new ActiveMQConnectionFactory(brokerUser,
brokerPassword, brokerUrl);
}
I already tried to add #EnableJms to Application with no success. The stack error is the follow:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'jmsListenerContainerFactory' defined in class
path resource
[org/springframework/boot/autoconfigure/jms/JmsAnnotationDrivenConfiguration.class]:
Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate
[org.springframework.jms.config.DefaultJmsListenerContainerFactory]:
Factory method 'jmsListenerContainerFactory' threw exception; nested
exception is java.lang.NoSuchMethodError:
org.springframework.jms.config.DefaultJmsListenerContainerFactory.setAutoStartup(Z)V
Thank's in advanced and sorry about any mistake in question.
Apparently it's a bug of spring boot 1.3.3:
DefaultJmsListenerContainerFactory does not contains the required method.
Try to upgrade to spring boot 1.4.0 (in spite it is not in RELEASE version at the moment).
That should solve the bug.
I encountered the same Exception and read the answers here. Because I'm using Spring boot 1.5.1-RELEASE, I found the answers not to be applicable and continued my search.
What I found to be the cause on my end was not properly reading the manual:
http://camel.apache.org/activemq.html. The introduction states:
To use this component make sure you have the activemq.jar or activemq-core.jar on your classpath along with any Camel dependencies such as camel-core.jar, camel-spring.jar and camel-jms.jar.
So what solved the problem was 2 extra Maven entries.
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>${apache.camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
<version>${apache.camel.version}</version>
</dependency>
I hope it helps someone.
If somebody meet with this issue I found solution.
We need to downgrade version of spring-boot to 1.2.3.RELEASE, because camel-jms:2.16.2 uses spring components in version 4.1.9.
Having this configuration :
#Configuration
#EnableNeo4jRepositories("com.mydb.repository")
#EnableTransactionManagement
public class Neo4jConfig extends Neo4jConfiguration {
#Bean
#Override
public Neo4jServer neo4jServer() {
return new RemoteServer( "http://localhost:7474" );
}
#Bean
public GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabaseBuilder( new File("./mydb.db") )
.setConfig( ServerSettings.auth_enabled, Boolean.FALSE.toString() )
.newGraphDatabase();
}
#Bean
#Override
#Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
public Session getSession() throws Exception {
return super.getSession();
}
#Bean
#Override
public SessionFactory getSessionFactory() {
return new SessionFactory("com.mydb.model");
}
}
I have 2 errors :
1_ I can't keep the Session in scope "session"
2_ I have the exception : Connect to localhost:7474 failed: Connection refused:
The server is Embedded, it should start without instaling any server on my local machine ?
Spring-boot 1.3.0 (Last) and
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
Version 4.0 of Spring Data for Neo4j doesn't support embedded version of Neo4j.
You need to install Neo4j on your local machine.
"SDN 4.1 will support embedded version." #Luanne