spring boot with java + groovy _maven in embedded tomcat, controller but error - rest

Sorry if this is already answered, I am not able to find it.
I have created new project using spring boot.
My requirements are that I have some java classes, some groovy classes and they should be able to call each others.
I am using maven and running my embedded tomcat by
mvn spring-boot:run
Problem is, RestController which is Java Class is there and I am able to call it REST URL.
But the controller which is in Groovy, is not able to be called and gives me error.
curl localhost:8080/
{"timestamp":1455913384508,"status":404,"error":"Not Found","message":"No message available","path":"/"}
Good part is that I am able to call groovy class from java.
Below are my files.
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-spring-boot</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.3.7</version>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<!-- 2.8.0-01 and later require maven-compiler-plugin 3.1 or higher -->
<version>3.1</version>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>2.9.1-01</version>
</dependency>
<!-- for 2.8.0-01 and later you must have an explicit dependency on
groovy-eclipse-batch -->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>2.3.7-01</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
app.groovy:
package hello
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
#RestController
class ThisWillActuallyRun {
#RequestMapping("/home")
String home() {
return "Hello World!"
}
}
Application.java
package hello;
import java.util.Arrays;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
}
}
Controller class
package hello;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
#RestController
public class HelloController {
#RequestMapping("/hello")
public String index() {
ThisWillActuallyRun t = new ThisWillActuallyRun() ;
String v = t.home() ;
System.out.println("value from groovy="+v) ;
return "Greetings from Spring Boot!";
}
}
This works:
curl localhost:8080/hello
Greetings from Spring Boot!
Thanks a lot for the help.

I don't see a problem with your Groovy controller ThisWillActuallyRun
One concern I would have is that you have 2 separate controllers, but did not provide a #RequestMapping(path="controllerpath") at the top of your class on each controller. You did not specify a unique context (relative path) to your controller.
In addition, your curl command only goes to "/". I don't see any mapping for that.
It may work if you curl to "/home", just like you did for "/hello". Regardless, it is a better practice to give a controller level path as well.
An example of how the URL would look if you annotated the #RequestMapping at the top of your 2 controllers might look like:
#RestController
#RequestMapping(path="destination")
class ThisWillActuallyRun {
#RequestMapping("/home")
String home() { }
}
#RestController
#RequestMapping(path="greeting")
public class HelloController {
#RequestMapping("/hello")
public String index() {}
}
Then to reach the 2 endpoints would look like:
http://localhost:8080/destination/home
http://localhost:8080/greeting/hello

Related

RestClient Error javax.ws.rs.WebApplicationException: Unknown error, status code 404

I'm trying to request from a Quarkus's api to Jersey's api, but Jersey API returns a 404 error:
javax.ws.rs.WebApplicationException: Unknown error, status code 404
It looks like quarkus rest client doesn't recognize or can't parse the payload json.
Did you already get something like that?
the payload should be something like that:
{
"code": 404,
"description": "some description....",
"label": "API_ERROR_OBJECT_NOT_FOUND",
"message": "Requested Object not found"
}
The code:
#ApplicationScoped
public class MachineService {
#Inject
#RestClient
ICoreSummaryRest iCoreSummaryRest;
public Boolean transferDatacollector(ObjectNode transferDatacollector) {
try {
String resp = iCoreSummaryRest.updateDataCollectosTransfer
(transferDatacollector.toString());
return Boolean.valueOf(resp);
}catch (Exception e){
return null;
}
}
interface
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
#Path("/")
#RegisterRestClient(configKey="country-api")
#RegisterClientHeaders(CustomHeadersRest.class)
public interface ICoreSummaryRest {
#PUT
#Produces(MediaType.APPLICATION_JSON)
#Path("datacollectors/transfer/")
public String updateDataCollectosTransfer(String transferDatacollectorJSON);
}
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>
<!-- The Basics -->
<parent>
<groupId>com.mycompany</groupId>
<artifactId>my-project</artifactId>
<version>1.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>my-project-resource</artifactId>
<version>1.0.0</version>
<dependencies>
<!-- Dependências Gerais Quarkus BOM -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
<artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-openapi</artifactId>
<scope>provided</scope>
</dependency>
<!-- <dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-graphql</artifactId>
</dependency> -->
<dependency>
<groupId>org.eclipse.microprofile.rest.client</groupId>
<artifactId>microprofile-rest-client-api</artifactId>
</dependency>
<!-- Dependências do Projeto -->
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>my-project-service</artifactId>
<scope>provided</scope>
</dependency>
<!-- Dependência JTS -->
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
</dependency>
<!-- Dependência mycompany -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
<!-- Build Settings -->
<build>
<plugins>
<plugin>
<groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
If you want to read the body you can catch the error like this:
try {
String resourceResponse = errorRestClient.getResource();
} catch (WebApplicationException e) {
String respStr = e.getResponse().readEntity(String.class);
LOGGER.error(respStr);
}
Which will print this for the following mockbin at http://mockbin.org/bin/3144eda0-9fa7-4893-90ee-5d624d51bcd2
2022-01-30 17:59:45,851 ERROR [org.acm.arc.ErrorHTTPrestAPI]
(vert.x-eventloop-thread-11) { "description": "some
description....",
"label": "API_ERROR_OBJECT_NOT_FOUND",
"message": "Requested Object not found" }
My interface looks like this
#ApplicationScoped
#Path("/")
#RegisterRestClient(baseUri="http://mockbin.org/bin/3144eda0-9fa7-4893-90ee-5d624d51bcd2")
public interface ErrorRestClient {
#GET
#Path("")
String getResource();
}
If I understood correctly this issue,
when RestClient receives one response different from 2xx it automatically throws this exception.
Perhaps you can disable the ResponseExceptionMapper or create one interceptor to handle this exception.
Below I just quote the answer from this issue
This exception is thrown by the default rest client ResponseExceptionMapper.
You should be able to disable it by adding the following property to application.properties:
microprofile.rest.client.disable.default.mapper=false
See the Default ResponxeExceptionMapper and ResponseExceptionMapper sections of the MicroProfile Rest Client specification.

Apache Camel routing API call to message queue

I have two applications that talk to each other using a REST API.
I would like to know if I can use Apache Camel as a proxy that could "persist" the API calls, for example storing them as messages in ActiveMQ, and then later route the requests to the actual API endpoint.
Practically, I would like to use Apache Camel to "enhance" the API endpoints adding persistence, throttling of requests, etc...
What component do you suggest to use?
You can always try to bridge your HTTP request into a queue, but making the thread wait by forcing the exchangePattern to InOut.
See this example :
import org.apache.activemq.broker.BrokerService;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
private static final Logger logger = LoggerFactory.getLogger(SimpleRouteBuilder.class);
public static void main(String[] args) throws Exception {
org.apache.camel.main.Main main = new org.apache.camel.main.Main();
main.addRouteBuilder(new SimpleRouteBuilder());
logger.info("Next call is blocking, ctrl-c to exit\n");
main.run();
}
}
class SimpleRouteBuilder extends RouteBuilder {
private static final Logger logger = LoggerFactory.getLogger(SimpleRouteBuilder.class);
public void configure() throws Exception {
// launching an activemq in background
final BrokerService broker = new BrokerService();
broker.setBrokerName("activemq");
broker.addConnector("tcp://localhost:61616");
Runnable runnable = () -> {
try {
broker.start();
} catch (Exception e) {
e.printStackTrace();
}
};
runnable.run();
// receiving http request but queuing them
from("jetty:http://127.0.0.1:10000/input")
.log(LoggingLevel.INFO, logger, "received request")
.to("activemq:queue:persist?exchangePattern=InOut"); // InOut has to be forced with JMS
// dequeuing and calling backend
from("activemq:queue:persist")
.log(LoggingLevel.INFO, logger,"requesting to destination")
.removeHeaders("CamelHttp*")
.setHeader("Cache-Control",constant("private, max-age=0,no-store"))
.to("jetty:http://perdu.com?httpMethod=GET");
}
}
If you are using maven, here is the pom.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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>be.jschoreels.camel</groupId>
<artifactId>camel-simple</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.19.2</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
<version>2.19.2</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jetty</artifactId>
<version>2.19.2</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-camel</artifactId>
<version>5.15.3</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-kahadb-store -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-kahadb-store</artifactId>
<version>5.15.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>

No test results with Eclipse + Maven + Cucumber + Serenity

Okay so I have read just about every online tutorial I can find. I am trying to setup BDD test automation for a simple dating app for now. The online documentation for doing all of this in Eclipse is really poor. I have gotten it run in Eclipse and I get a test file in index.html but it is saying say there are no tests.
I am running the tests by right clicking the project and doing 'Run As' Maven build and for 'Run Configurations' I am doing clean test verify. Here is how I am organizing my projects.
Here is my SearchByGender.java file
package sean;
//package net.serenity_bdd.samples.etsy.features;
import cucumber.api.CucumberOptions;
import net.serenitybdd.cucumber.CucumberWithSerenity;
import org.junit.runner.RunWith;
#RunWith( CucumberWithSerenity.class )
#CucumberOptions( features="src/test/resources/features/verify_gender.feature" )
public class SearchByGender {}
And here is my SearchByGenderStepDefinitions.java file
package sean;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import net.thucydides.core.annotations.Steps;
public class SearchByGenderStepDefinitions
{
#Steps
UserProfile profile;
#Given( "I want a (.*)" )
public void userWantsToFind()
{
profile.opens_user_profile();
}
#When( "I search for profiles containing '(.*)'" )
public void searchByGender( String gender )
{
profile.searches_for_profiles_containing( gender );
}
#Then( "I should only see profiles related to '(.*)'" )
public void resultsForGender( String gender )
{
profile.should_see_profiles_related_to( gender );
}
}
My UserProfile.java
package sean;
import net.thucydides.core.annotations.Step;
import net.thucydides.core.steps.ScenarioSteps;
import static org.assertj.core.api.Assertions.assertThat;
public class UserProfile extends ScenarioSteps
{
private static final long serialVersionUID = 1L;
private String searched_gender;
private String status;
#Step
public void opens_user_profile()
{
status = "single";
}
#Step
public void searches_for_profiles_containing( String searched_gender )
{
this.searched_gender = searched_gender;
}
#Step
public void should_see_profiles_related_to( String found_gender )
{
assertThat( searched_gender.equals(found_gender) );
}
}
My feature file
Feature: Searching by gender
In order to find a girlfriend
As a single male
I want to be able to profiles containing female
Scenario: Should list profiles related to a specified gender
Given I want a girlfriend
When I search for profiles containing 'female'
Then I should only see profiles related to 'female'
And lastly here is my 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>net.serenity_bdd.samples.junit</groupId>
<artifactId>junit-quick-start</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Serenity JUnit Quick Start Project</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<serenity.version>1.0.47</serenity.version>
<serenity.maven.version>1.0.47</serenity.maven.version>
<webdriver.driver>firefox</webdriver.driver>
</properties>
<dependencies>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>core</artifactId>
<version>${serenity.version}</version>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-junit</artifactId>
<version>${serenity.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-cucumber</artifactId>
<version>1.0.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18</version>
<configuration>
<includes>
<include>**/features/**/When*.java</include>
</includes>
<systemProperties>
<webdriver.driver>${webdriver.driver}</webdriver.driver>
<surefire.rerunFailingTestsCount>${surefire.rerunFailingTestsCount}</surefire.rerunFailingTestsCount>
<surefire.rerunFailingTestsCount>${surefire.rerunFailingTestsCount}</surefire.rerunFailingTestsCount>
</systemProperties>
</configuration>
</plugin>
<plugin>
<groupId>net.serenity-bdd.maven.plugins</groupId>
<artifactId>serenity-maven-plugin</artifactId>
<version>${serenity.maven.version}</version>
<dependencies>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>core</artifactId>
<version>${serenity.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>serenity-reports</id>
<phase>post-integration-test</phase>
<goals>
<goal>aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Please help. I have to get this working for my job.
I fixed the problem by creating an new Maven project in Eclipse with the serenity-cucumber archetype. Before I was just doing a quickStart. Don't know why this fixed the problem but it did. Probably has something to do with plugins.

No injection source found for a parameter of type public javax.ws.rs.core.Response - Jersey - MultiPartFeature

I'm creating a web service with Jersey and Jetty Embedded with no web.xml file. It is very simple, It receive a binary file by a POST from a HTML form. It seems I didn't register the MultiPart Feature properly because When I try to use it with HTML form I get this error :
*
WARNING: No injection source found for a parameter of type public
javax.ws.rs.core.Response
org.multipart.demo.ReceiveFile.postMsg(java.io.InputStream,org.glassfish.jersey.media.multipart.FormDataContentDisposition)
throws java.lang.Exception at index 0. 2016-02-09
21:49:59.916:WARN:/:qtp1364335809-16: unavailable
org.glassfish.jersey.server.model.ModelValidationException: Validation
of the application resource model has failed during application
initialization.|[[FATAL] No injection source found for a parameter of
type public javax.ws.rs.core.Response
org.multipart.demo.ReceiveFile.postMsg(java.io.InputStream,org.glassfish.jersey.media.multipart.FormDataContentDisposition)
throws java.lang.Exception at index 0.;
source='ResourceMethod{httpMethod=POST,
consumedTypes=[multipart/form-data], producedTypes=[text/plain],
suspended=false, suspendTimeout=0,
I was looking for the solution for weeks, I have read all question related to this error on StackOverflow, for instance:
MULTIPART_FORM_DATA: No injection source found for a parameter of type public javax.ws.rs.core.Response
Jersey 2 injection source for multipart formdata
They didn't help me because Im not using web.xml
I have 3 classes
- ReceiveFile.class (try to receive the POST)
- resourceConfig.class (try to register the MultiPart feature)
- JettyServer.class (create server instance)
ReceiveFile.class
package org.multipart.demo;
import java.io.InputStream;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
#Path("/resources")
public class ReceiveFile
{
#POST
#Path("/fileUpload")
#Produces("text/plain")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response postMsg (
#FormDataParam("file") InputStream stream,
#FormDataParam("file") FormDataContentDisposition fileDetail) throws Exception {
Response.Status respStatus = Response.Status.OK;
return Response.status(respStatus).build();
}
}
resourceConfig.class
package org.multipart.demo;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
/**
* Registers the components to be used by the JAX-RS application
*
*/
#ApplicationPath("/resources/fileUpload")
public class resourceConfig extends ResourceConfig {
/**
* Register JAX-RS application components.
*/
public resourceConfig(){
register(ReceiveFile.class);
register(JettyServer.class);
register(MultiPartFeature.class);
//packages("org.glassfish.jersey.media", "com.mypackage.providers");
}
}
JettyServer.class
package org.multipart.demo;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
public class JettyServer
{
// private static final Logger LOGGER = Logger.getLogger(UploadFile.class.getName());
public static void main(String[] args) throws Exception
{
ResourceConfig config = new ResourceConfig();
config.packages("org.multipart.demo");
Server jettyServer = new Server(8080);
ResourceHandler resource_handler = new ResourceHandler();
// Configure the ResourceHandler. Setting the resource base indicates where the files should be served out of.
// In this example it is the current directory but it can be configured to anything that the jvm has access to.
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[]{ "./index.html" , "./html/FileUpload.html" });
resource_handler.setResourceBase(".");
//Jersey ServletContextHandler
final ResourceConfig resourceConfig = new ResourceConfig(ReceiveFile.class);
resourceConfig.register(MultiPartFeature.class);
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
ServletHolder jerseyServlet = servletContextHandler.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*" );
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, "org.multipart.demo");
// Add the ResourceHandler to the server.
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, servletContextHandler, new DefaultHandler() });
jettyServer.setHandler(handlers);
try {
jettyServer.start();
jettyServer.join();
} finally {
jettyServer.destroy();
}
}
}
the 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</groupId>
<artifactId>multipart.demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>multipart.demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.2.3.v20140905</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.2.3.v20140905</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.jvnet.mimepull</groupId>
<artifactId>mimepull</artifactId>
<version>1.9.6</version>
</dependency>
</dependencies>
</project>
Thanks in advance!
I See three different ResourceConfigs in your codebase, but none of them are actually used for the application. So the MultiPartFeature is never register, which is what is causing the error. You have a few options on how to use a ResourceConfig in your case.
You can instantiate the ServletContainer, passing in the ResourceConfig instance. Unfortunately, there is no ServletContextHolder#addServlet(Servlet) method, but there is a ServletContextHolder#addServlet(ServletHolder) method, so we need to wrap the ServletContainer in a ServletHolder
ServletHolder jerseyServlet = new ServletHolder(new ServletContainer(resourceConfig));
servletContextHolder.addServlet(jerseyServlet, "/*");
With the above option, you can use a local instance or a subclass, but if you only have a subclass, like your first bit of code, then you add a servlet init param, that specifies the ResourceConfig subclass.
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
ServletHolder jerseyServlet = servletContextHandler.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*" );
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, "org.multipart.demo");
jerseyServlet.setInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, resourceConfig.class.getCanonicalName());
Notice the last call where I set the application class name.
Without using a ResourceConfig, you could just register the MulitPartFeature with an init param
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, MultiPartFeature.class.getCanonicalName());

hadoop 2.6 cluster cannot be initialized. Successfully run with local jars, but not maven dependency

I'm trying to debug wordcount sample using apache hadoop 2.6.0.I create the project in eclipse. My first try was configure the build path and include all the hadoop jar files (extracted from hadoop folder) in the buildpath. I can successfully run the word count and get the result. Then my second try is to make this project a 'maven' project and using pom.xml to specify needed hadoop jars (and remove local jars in buildpath). Here comes the problem. This time exception throws as follows:
Exception in thread "main" java.io.IOException: Cannot initialize Cluster. Please check your configuration for mapreduce.framework.name and the correspond server addresses.
at org.apache.hadoop.mapreduce.Cluster.initialize(Cluster.java:120)
at org.apache.hadoop.mapreduce.Cluster.<init>(Cluster.java:82)
at org.apache.hadoop.mapreduce.Cluster.<init>(Cluster.java:75)
at org.apache.hadoop.mapreduce.Job$9.run(Job.java:1266)
at org.apache.hadoop.mapreduce.Job$9.run(Job.java:1262)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1628)
at org.apache.hadoop.mapreduce.Job.connect(Job.java:1261)
at org.apache.hadoop.mapreduce.Job.submit(Job.java:1290)
at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1314)
at WordCount.main(WordCount.java:59)
My wordcount code is pretty simple and classic wordcount.
import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WordCount {
public static class TokenizerMapper
extends Mapper<Object, Text, Text, IntWritable>{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context
) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
public static class IntSumReducer
extends Reducer<Text,IntWritable,Text,IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values,
Context context
) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path("/home/jsun/share/wc/input"));
FileOutputFormat.setOutputPath(job, new Path("/home/jsun/share/wc/output"));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
And the pom.xml for maven:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/1/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>wordcount2</groupId>
<artifactId>wordcount2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<repositories>
<repository>
<id>apache</id>
<url>http://central.maven.org/maven2/</url>
</repository>
</repositories>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.6.0</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
What is the difference using local hadoop jars and using maven dependencies?
Is that a problem of cluster or the wordcount or using maven?
Thanks in advance.
please check this Link
i had the same issue and i don't have hadoop installed on my machine. you can't run the program without installation. i think it looks for some environment variables to run hadoop commands.
Hope this helps