I am trying to config embedded neo4j with spring boot. But after getting so much trouble with version of different package I came up with this
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
<version>1.5.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-embedded-driver</artifactId>
<version>2.1.6</version>
<scope>compile</scope> <!--compatible with spring-boot-starter-data-neo4j 1.5.8.RELEASE-->
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>3.1.0</version>
<scope>runtime</scope>
</dependency>
This are the dependency of a graph module which is a dependency of rest module.
When I start the server everything go right but when I try to access neo4j server with this code.
#Service
public class FileBasedImportServiceImpl implements ImportService {
private Session session;
#Autowired
public FileBasedImportServiceImpl(Session session) {
this.session = session;
}
#Transactional
public void clearDatabase() {
session.purgeDatabase();
}
#Transactional
public void load() {
StringBuilder sb = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("school.cql")));
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append(" ");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
String cqlFile = sb.toString();
session.query(cqlFile, Collections.EMPTY_MAP);
}
}
by calling load() method in a controller, I get connection refused.
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to localhost:7474 [localhost/127.0.0.1] failed: Connection refused (Connection refused)
I think that the embedded neo4j didn't start that's why. So how to make the embedded server start. I was thinking it will start automatically if I use spring boot but it wasn't the case.
Note: the file school.cql contains cypher query
this is the project that I followed https://github.com/neo4j-examples/sdn-university
I have already add the annotation to my main class #EntityScan("com")
Thank you.
Update
This is the configuration annotation of spring application
#ComponentScan(basePackages={"com"})
#Configuration
#EnableJpaRepositories("com.repository")
#EntityScan(basePackages = {"com.domain", "org.springframework.data.jpa.convert.threeten"})
#EnableConfigurationProperties
#EnableAutoConfiguration
#EnableScheduling
#SpringBootApplication(exclude = org.activiti.spring.boot.SecurityAutoConfiguration.class)
#EnableNeo4jRepositories("com.graph.repository")
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
Like I said I have followed this tutorial https://github.com/neo4j-examples/sdn-university and the only thing that I have done different is making two maven module instead of one for the graph that contains the repository/ domain entities/service related to neo4j. The other module is related to spring boot and to rest controller
SO I have found the problem
Spring boot doesn't detect neo4j dependency
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>3.1.0</version>
<scope>runtime</scope>
</dependency>
If it is not in the same pom.xml as the spring-boot maven plugin.
So in other word transitive dependency doesn't work.
Related
On base of the guide from this blog, Roll your own Auto Discovery with Jersey and HK2, I have the follow resource POJO:
#Path("Test")
public class TestResource {
#Inject
private TestService service;
#GET
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Set<Test> getTests() {
return service.getAllTests();
}
}
The TestService:
#Contract
public interface TestService {
public Set<Test> getAllTests();
}
The TestServiceImpl
#Service
public class TestServiceImpl implements TestService {
#Override
public Set<Test> getAllTests() {
Set<Test> tests = new HashSet<>();
Test c = new Test();
c.setName("test");
tests.add(c);
return tests;
}
}
The Jersey dependency in pom.xml is of version 2.25.1
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<dependency>
<groupId>org.glassfish.jersey.bundles</groupId>
<artifactId>jaxrs-ri</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>hk2</artifactId>
<version>2.5.0-b36</version>
</dependency>
In order to make Jersey scan the #Service and #Contract classes automatically, I used the inhabitant-generator plugin with version 2.5.0-b36:
<plugin>
<groupId>org.glassfish.hk2</groupId>
<artifactId>hk2-inhabitant-generator</artifactId>
<version>2.5.0-b36</version>
<executions>
<execution>
<goals>
<goal>generate-inhabitants</goal>
</goals>
</execution>
</executions>
</plugin>
There is the corresponding Feature implementation:
public class AutoServiceDiscovery implements Feature {
#Override
public boolean configure(FeatureContext context) {
ServiceLocator locator = ServiceLocatorProvider.getServiceLocator(context);
DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
Populator populator = dcs.getPopulator();
try {
populator.populate(new ClasspathDescriptorFileFinder(this.getClass().getClassLoader()),
new DuplicatePostProcessor());
} catch (IOException | MultiException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
return true;
}
}
And it is indeeded registered through my ResourceConfig class:
#ApplicationPath("/*")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
packages("resources");
register(new AutoServiceDiscovery());
}
}
However, I send request to the /test, got the following error:
MultiException has 3 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for
injection at SystemInjecteeImpl(requiredType=TestService,parent=TestResource,qualifiers=
{},position=-1,optional=false,self=false,unqualified=null,1947073589)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of
rx.practice.ee.jaxrs.resources.TestResource errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on
rx.practice.ee.jaxrs.resources.TestResource
org.jvnet.hk2.internal.Collector.throwIfErrors(Collector.java:89)
org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:250)
org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:358)
org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:487)
org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
...
Question: Anyone knows why the #Service class cannot be injected? I am using Tomcat server
After a couple of days research on the source code of inhabitat-generator, I figured out that in case of web application package,war, the locator file is not generated in META-INF/hk2-locator as demonstracted in the HK2 Inhabitant Generator office site in case of using jar as deployment package. The source code of AbstractInhabitantsGeneratorMojo.java told that in case of war, locator files are generated in hk2-locator, and this is not mentioned in the HK2 Inhabitant Generator office site.
However, when constructing the ClasspathDescriptorFileFinder without the directory names argument in the bootstrap class, AutoServiceDiscovery, it is only compatible with jar as deployment package, meaning it is only finding files in META-INF/hk2-locator.
So the better solution would be not to use inhabitant-generator plugin but the metadata-generator dependency, which is an annotation processor at compile time and, it is proved out-of-the-box.
If someone is persistent to using this plugin, he/she could create his/her own ClasspathDescriptorFileFinder so that it is able to find locator files from hk2-locator
Last but not least, I also tried to use the inhabitants-generator plugin's options to generate the locator files in hk2-locator, but this seems to be next to impossible as well
First of all is it a viable thing to embed Activiti into an API type application for use within that application or should Activiti be run standalone?
The error below is due to bean definition but I'm not sure where the beans should be defined and how - if thats correct approach for version 6. Our standards with Springhboot 2 is to annotate beans in java rather than xml context
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-04-10 21:17:43.924 ERROR 19516 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field runtimeService in ma.cvmeeting.workflow.WorkflowApplication$MyrestController required a bean of type 'org.activiti.engine.RuntimeService' 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.activiti.engine.RuntimeService' in your configuration.
Process finished with exit code 0
code:
import org.activiti.engine.RuntimeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
#SpringBootApplication
public class WorkflowApplication {
public static void main(String[] args) {
SpringApplication.run(WorkflowApplication.class, args);
}
#RestController
public static class MyrestController{
#Autowired
private RuntimeService runtimeService;
#GetMapping("/start-process")
public String startProcess() {
runtimeService.startProcessInstanceByKey("Potulerauneoffre");
return "Process started. Number of currently running"
+ "process instances = "
+ runtimeService.createProcessInstanceQuery().count();
}
}
pom.xml:
<project>
<groupId>ma.cvmeeting</groupId>
<artifactId>workflow</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>workflow</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>7-201802-EA</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.h2database</groupId>
<artifactId>h2database</artifactId>
<version>1.0.20061217</version>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
There are two ways to initialize the engine when you embed it in your spring based application:
1.) let spring initialize it for you so you can use all the engine services right away without need of any configuration. this requires activiti-spring-boot-starter as dependency.
2.) You initialize engine by your self and provide the services beans from #Configuration class. for this you will require only activiti-engine core as dependency
The reason your application cannot find the RuntimeService because you are trying the second approach add the below dependency in your pom.xml and remove the engine one
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
</dependency>
you should follow documentation for more help.
We recommend activiti 7 core if you are planning to use spring boot 2.x and the use of the new APIs. This is great time if you want to get involved with the new APIs and project initiatives
You could write a #Configuration class and define Activiti services, like this :
#Configuration
public class ActivityConfig {
#Autowired
DataSource dataSource;
#Bean
public DataSourceTransactionManager getTransactionManager() {
return new DataSourceTransactionManager(dataSource);
}
#Bean
public ProcessEngineConfigurationImpl getProcessEngineConfiguration() {
SpringProcessEngineConfiguration res = new SpringProcessEngineConfiguration();
res.setDataSource(dataSource);
res.setTransactionManager(getTransactionManager());
return res;
}
#Bean
public ProcessEngineFactoryBean getProcessEngine() {
ProcessEngineFactoryBean res = new ProcessEngineFactoryBean();
res.setProcessEngineConfiguration(getProcessEngineConfiguration());
return res;
}
#Bean
public RepositoryService getRepositoryService() throws Exception {
return getProcessEngine().getObject().getRepositoryService();
}
#Bean
public FormService getFormService() throws Exception {
return getProcessEngine().getObject().getFormService();
}
#Bean
public TaskService getTaskService() throws Exception {
return getProcessEngine().getObject().getTaskService();
}
#Bean
public RuntimeService getRuntimeService() throws Exception {
return getProcessEngine().getObject().getRuntimeService();
}
#Bean
public HistoryService getHistoryService() throws Exception {
return getProcessEngine().getObject().getHistoryService();
}
#Bean
public IdentityService getIdentityService() throws Exception {
return getProcessEngine().getObject().getIdentityService();
}
}
I already went through the link: Unable to connect to Command Metric Stream for Hystrix Dashboard with Spring Cloud and tried few options, but nothing worked out for yet.
I am developing Spring Cloud Code + Hystrix + Turbine.
Could you please let me know what is the issue ? I am using Spring Boot v2.0.4.RELEASE.
HystrixDashboardApplication.java
#EnableTurbine
#EnableHystrixDashboard
#SpringBootApplication
public class HystrixDashboardApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardApplication.class, args);
}
}
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.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>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
tollrate-billboard application has the following code
TollrateBillboardApplication.java
#EnableCircuitBreaker
#SpringBootApplication
#EnableEurekaClient
public class TollrateBillboardApplication {
public static void main(String[] args) {
SpringApplication.run(TollrateBillboardApplication.class, args);
}
}
DashboardController.java
#Controller
public class DashboardController {
#LoadBalanced
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
#Autowired
private RestTemplate restTemplate;
#HystrixCommand(fallbackMethod = "getTollRateBackup")
#RequestMapping("/dashboard")
public String GetTollRate(#RequestParam int stationId, Model m) {
TollRate tr = restTemplate.getForObject("http://pluralsight-toll-service/tollrate/" + stationId, TollRate.class);
System.out.println("stationId: " + stationId);
m.addAttribute("rate", tr.getCurrentRate());
return "dashboard";
}
public String getTollRateBackup(#RequestParam int stationId, Model m) {
System.out.println("Fallback operation called");
m.addAttribute("rate", "1.00");
return "dashboard";
}
}
bootstrap.properties
spring.application.name=pluralsight-tollrate-billboard
application.properties
server.port=8082
# eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
#http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html#_environment_changes
management.endpoints.web.exposure.include=hystrix.stream
CURL Command Result:
curl "http://localhost:8085/clusters"
output
[
{
"name": "PLURALSIGHT-FASTPASS-CONSOLE",
"link": "http://localhost:8085/turbine.stream?cluster=PLURALSIGHT-FASTPASS-CONSOLE"
},
{
"name": "PLURALSIGHT-TOLLRATE-BILLBOARD",
"link": "http://localhost:8085/turbine.stream?cluster=PLURALSIGHT-TOLLRATE-BILLBOARD"
}
]
EDIT-1::, I am using "hystrix-turbine"
#EnableTurbineStream
#SpringBootApplication
public class HystrixTurbineApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixTurbineApplication.class, args);
}
}
Now, I'm getting below error:
2018-09-03 22:23:45.808 WARN 2820 --- [nio-8085-exec-5] ashboardConfiguration$ProxyStreamServlet : Failed opening connection to http://localhost:8085/turbine.stream?cluster=PLURALSIGHT-FASTPASS-CONSOLE : 404 : HTTP/1.1 404
2018-09-03 22:23:45.808 WARN 2820 --- [nio-8085-exec-2] ashboardConfiguration$ProxyStreamServlet : Failed opening connection to http://localhost:8085/turbine.stream?cluster=PLURALSIGHT-FASTPASS-CONSOLE : 404 : HTTP/1.1 404
#Sayali I tried recreating the error in my own system and I managed to get it working, here are a few checks you can make:
1) The URL in your 1st screenshot is incorrect. Your stream URL in the Hystrix Dashboard should be:
http://localhost:8085/turbine.stream?cluster=PLURALSIGHT-TOLLRATE-BILLBOARD
The url should be pointing to the port of the dashboard application that has #EnableTurbine annotation in your main class.
2) Check if you are getting a response for:
http://localhost:8082/actuator/hystrix.stream
(use your browser for this)
(this should be coming from the application you have enabled hystrix on using #EnableCircuitBreaker)
If you're getting pings, then atleast your hystrix stream is accessible.
If not,
Check if you have: org.springframework.boot:spring-boot-starter-actuator in dependencies and
make sure you have the below property set in application.properties file of the application that has #EnableCircuitBreaker in the main class:
management.endpoints.web.exposure.include= hystrix.stream, info, health
Check the URL again.
3) Please get the turbine section working before moving to turbine streams, so as of now, you can make the following change:
#EnableTurbine // instead of #EnableTurbineStream
#SpringBootApplication
public class HystrixTurbineApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixTurbineApplication.class, args);
}
}
Also, to use TurbineStream:
you might want to have your Hystrix commands push metrics to Turbine.
Spring Cloud enables that with messaging. To do so on the client, add
a dependency to spring-cloud-netflix-hystrix-stream and the
spring-cloud-starter-stream-* of your choice.
refer: http://cloud.spring.io/spring-cloud-static/Finchley.SR1/single/spring-cloud.html#_turbine_stream
I hope this helps. Please comment to help me know if this worked for you.
sorry late reply.
Add following configuration to instance that serve hystrix.stream
hystrix.dashboard.proxyStreamAllowList: '**'
I'm attempting to set up a simple REST web application that uses Jersey. In the documentation, it seems that I should be able to create my application without using a web.xml file. From the site:
JAX-RS provides a deployment agnostic abstract class Application for declaring root resource and provider classes, and root resource and provider singleton instances. A Web service may extend this class to declare root resource and provider classes.
The example that follows shows this code:
public class MyApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(HelloWorldResource.class);
return s;
}
}
To me, this says that I can use an Application class to do all of my servlet setup. This seems to be the configuration that reads my resource class's annotations and sets up the correct URL handling mechanisms. Is that correct? I don't have to do any other setup?
I ask because I created the following and it didn't work (I get a 404 from localhost:8080/{context}/test):
pom.xml:
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.12</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.12</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.12</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
Application class:
#ApplicationPath("/")
public class JerseyTestApp extends Application
{
#Override
public Set<Class<?>> getClasses()
{
final Set<Class<?>> classes = new HashSet<>();
classes.add(JerseyTestController.class);
return classes;
}
}
Resource class:
#Path("/test")
public class JerseyTestController
{
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getTestMsg()
{
return "It works";
}
}
Dumb. All I had to do was include the jersey-servlet jar, as prescribed by this answer.
I have a Standalone Jersey server running at the beginning of my JunitTest. I'm testing if my JaxRS controller works, as well as my custom HttpClient. Please note that I've always been able to use this JaxRsResourceController embedded in glassfish.
Here is the JaxRsController (light version)
#Path("root")
public class JaxRsResourceController implements
ResourceController<HttpServletRequest> {
#Context
private UriInfo context;
#Context
HttpServletRequest request;
#Context
HttpServletResponse response;
#GET
public String hello(){
System.out.println("Uri is "+this.context.getBaseUri().toString());
return "Hello "+peoples;
}
}
I have no problem with the client, but when I start the server, I have :
GRAVE: The following errors and warnings have been detected with resource and/or provider classes:
SEVERE: Missing dependency for field: javax.servlet.http.HttpServletRequest com.robustaweb.library.rest.controller.implementation.JaxRsResourceController.request
SEVERE: Missing dependency for field: javax.servlet.http.HttpServletResponse com.robustaweb.library.rest.controller.implementation.JaxRsResourceController.response
at com.sun.jersey.api.container.httpserver.HttpServerFactory.create(HttpServerFactory.java:172)
at com.robustaweb.library.rest.server.JerseyServer.startServer(JerseyServer.java:44)
Basically it says that at the #Context injection time, there is no dependency on the HttpServletRequest.
However if I remove the #Context annotations on request and response, but keep it for UriInfo context, it's ok, and I can read the Uri.
I changed a few times the Maven pom wich is now to force the libs in:
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
Any idea ?
servlet dependencies were separated to another module, try adding
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.14</version>
</dependency>
to your pom.
It was not easy, but I found out. The thing is that in my JUnit test, I was creating the server like this :
HttpServer server = HttpServerFactory.create(url);
But that way, you create a lightweight container that does not have servlet containers, and so is the failure reason. So in order to have it all, I used the jersey-test-framework that allow to use the Grizzly web container (or even Embedded glassfish).
Here is the maven :
<dependencies>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<!-- Unit test are using jersey server directly -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey.test.framework</groupId>
<artifactId>jersey-test-framework</artifactId>
<version>1.0.3</version>
<scope>test</scope>
</dependency>
</dependencies>
Here is the JerseyServerTest : note that it extends JerseyTest
public class JerseyServerTest extends JerseyTest {
protected String baseUri = "http://localhost:" + TestConstants.JERSEY_HTTP_PORT + "/";
public JerseyServerTest() throws Exception {
super("com.robustaweb.library.rest.controller");
/*
It's possible to NOT call the super() but to manually do :
1) ApplicationDescriptor appDescriptor = new ApplicationDescriptor()
.setRootResourcePackageName(resourcePackageName) // resource packages
.setContextPath(contextPath) //context of app
.setServletPath(servletPath); // context of spi servlet
2)setupTestEnvironment(appDescriptor);
*/
}
#Test
public void testHelloWorldRequest() {
SunRestClient client = new SunRestClient(baseUri + "root");
String result = client.GET("", null);
System.out.println(result);
}
#Test
public void testDeleteRequest() {
SunRestClient client = new SunRestClient(baseUri + "root");
String result = client.DELETE("john", null);
System.out.println(result);
}
}
And finally the Resource file, that contains #GET and #DELETE
#Path("root")
public class JaxRsController extends JaxRsResourceController{
List<String> peoples = new ArrayList<String>();
#GET
public String hello(){
System.out.println("Uri is "+getUri());
return "Hello "+peoples;
}
#DELETE
#Path("{name}")
public String deletePeople(#PathParam("name") String name){
System.out.println("deleting "+name);
this.peoples.remove(name);
return String.valueOf(peoples.size());
}
}
And now it works !
I had some help in this article, and there is a small chapter on the documentation. Beeing able to attach the source code of the Jersey framework really helped, so thantks to IntelliJ also.