Email service by it.ozimov can't see the send method - email

I implemented an email service form it.ozimov library. When everything was imported there is a problem with send method. I can't figure out how it should be imported, cause now the service can't see it.
Here it is dependency which I attach
<dependency>
<groupId>it.ozimov</groupId>
<artifactId>spring-boot-email-core</artifactId>
<version>0.4.2</version>
</dependency>
<dependency>
<groupId>it.ozimov</groupId>
<artifactId>spring-boot-freemarker-email</artifactId>
<version>0.4.2</version>
</dependency>
Here it is a service code
#Autowired
public EmailService emailService;
public void sendEmailWithoutTemplating() throws UnsupportedEncodingException {
final Email email = DefaultEmail.builder()
.from(new InternetAddress("cicero#mala-tempora.currunt", "Marco Tullio Cicerone "))
.to(Lists.newArrayList(new InternetAddress("titus#de-rerum.natura", "Pomponius AttÄ­cus")))
.subject("Laelius de amicitia")
.body("Firmamentum autem stabilitatis constantiaeque eius, quam in amicitia quaerimus, fides est.")
.encoding(String.valueOf(Charset.forName("UTF-8"))).build();
emailService.send(email);
}
Of course I added below code at properties:
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=name.surname#gmail.com
spring.mail.password=V3ry_Str0ng_Password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.scheduler.persistence.enabled=false
spring.mail.scheduler.persistence.redis.embedded=false
spring.mail.scheduler.persistence.redis.enabled=false

First, update the dependencies:
<dependency>
<groupId>it.ozimov</groupId>
<artifactId>spring-boot-email-core</artifactId>
<version>0.5.0</version>
</dependency>
<dependency>
<groupId>it.ozimov</groupId>
<artifactId>spring-boot-freemarker-email</artifactId>
<version>0.5.0</version>
</dependency>
Then, set the application properties:
spring.mail.host: smtp.gmail.com
spring.mail.port: 587
spring.mail.username: hari.seldon#gmail.com
spring.mail.password: Th3MuleWh0
spring.mail.properties.mail.smtp.auth: true
spring.mail.properties.mail.smtp.starttls.enable: true
spring.mail.properties.mail.smtp.starttls.required: true
Finally create a test service
package com.test;
import com.google.common.collect.Lists;
import it.ozimov.springboot.mail.model.Email;
import it.ozimov.springboot.mail.model.defaultimpl.DefaultEmail;
import it.ozimov.springboot.mail.service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.mail.internet.InternetAddress;
import java.io.UnsupportedEncodingException;
import static com.google.common.collect.Lists.newArrayList;
#Service
public class TestService {
#Autowired
private EmailService emailService;
public void sendEmail() throws UnsupportedEncodingException {
final Email email = DefaultEmail.builder()
.from(new InternetAddress("hari.seldon#the-foundation.gal",
"Hari Seldon"))
.to(newArrayList(
new InternetAddress("the-real-cleon#trantor.gov",
"Cleon I")))
.subject("You shall die! It's not me, it's Psychohistory")
.body("Hello Planet!")
.encoding("UTF-8").build();
emailService.send(email);
}
}
Pay extreme attention to the packages being imported.
Finally, you need to enable the extension in your main app using the annotation
#EnableEmailTools
You can find more in this article.

Related

Junit class failing after ACS Commons version upgrade to 5.3.4

I upgraded ACS Commons version from 5.0.6 to 5.3.4 in my project and now can see most of the test classes failing with below error
org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [io.wcm.testing.mock.aem.junit5.AemContext arg0] in method [void com.test.test.core.filters.LoggingFilterTest.doFilter(io.wcm.testing.mock.aem.junit5.AemContext) throws java.io.IOException,javax.servlet.ServletException]: Could not create io.wcm.testing.mock.aem.junit5.ResourceResolverMockAemContext instance.
at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameter(ExecutableInvoker.java:232)
at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameters(ExecutableInvoker.java:176)
at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameters(ExecutableInvoker.java:137)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:118)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:184)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:180)
a
Caused by: org.reflections.ReflectionsException: Scanner TypeAnnotationsScanner was not configured
at org.reflections.Store.get(Store.java:39)
at org.reflections.Store.get(Store.java:61)
at org.reflections.Store.get(Store.java:46)
Please find below my test class. I am using JUnit version as below
<dependency>
<groupId>io.wcm</groupId>
<artifactId>io.wcm.testing.aem-mock.junit5</artifactId>
<version>4.0.4</version>
<scope>test</scope>
</dependency>
Attaching the class below:
import java.io.IOException;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import org.apache.sling.testing.mock.sling.servlet.MockRequestPathInfo;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import io.wcm.testing.mock.aem.junit5.AemContext;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;
import uk.org.lidalia.slf4jext.Level;
import uk.org.lidalia.slf4jtest.LoggingEvent;
import uk.org.lidalia.slf4jtest.TestLogger;
import uk.org.lidalia.slf4jtest.TestLoggerFactory;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
#ExtendWith(AemContextExtension.class)
class LoggingFilterTest {
private LoggingFilter fixture = new LoggingFilter();
private TestLogger logger = TestLoggerFactory.getTestLogger(fixture.getClass());
#BeforeEach
void setup() {
TestLoggerFactory.clear();
}
#Test
void doFilter(AemContext context) throws IOException, ServletException {
MockSlingHttpServletRequest request = context.request();
MockSlingHttpServletResponse response = context.response();
MockRequestPathInfo requestPathInfo = (MockRequestPathInfo) request.getRequestPathInfo();
requestPathInfo.setResourcePath("/content/test");
requestPathInfo.setSelectorString("selectors");
fixture.init(mock(FilterConfig.class));
fixture.doFilter(request, response, mock(FilterChain.class));
fixture.destroy();
List<LoggingEvent> events = logger.getLoggingEvents();
assertEquals(0, events.size());
}
}
Does anyone know why it is failing with the ACS Commons version change?
This is like breaking lot many junit test classes

java.util.NoSuchElementException while executing junit Testrunner

Error I am getting is:
java.util.NoSuchElementException while running junit test. Here is full error from console in eclipse:
java.util.NoSuchElementException
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:970)
at java.base/java.util.Collections.max(Collections.java:713)
at io.cucumber.core.feature.FeatureParser.parseResource(FeatureParser.java:45)
at java.base/java.util.function.BiFunction.lambda$andThen$0(BiFunction.java:70)
at io.cucumber.core.resource.ResourceScanner.lambda$processResource$1(ResourceScanner.java:79)
at io.cucumber.core.resource.PathScanner$ResourceFileVisitor.visitFile(PathScanner.java:75)
at io.cucumber.core.resource.PathScanner$ResourceFileVisitor.visitFile(PathScanner.java:60)
at java.base/java.nio.file.Files.walkFileTree(Files.java:2811)
at io.cucumber.core.resource.PathScanner.findResourcesForPath(PathScanner.java:53)
at io.cucumber.core.resource.PathScanner.findResourcesForUri(PathScanner.java:31)
at io.cucumber.core.resource.ResourceScanner.findResourcesForUri(ResourceScanner.java:61)
at io.cucumber.core.resource.ResourceScanner.scanForResourcesUri(ResourceScanner.java:134)
at io.cucumber.core.runtime.FeaturePathFeatureSupplier.loadFeatures(FeaturePathFeatureSupplier.java:62)
at io.cucumber.core.runtime.FeaturePathFeatureSupplier.get(FeaturePathFeatureSupplier.java:45)
at io.cucumber.junit.Cucumber.<init>(Cucumber.java:156)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.internal.requests.ClassRequest.createRunner(ClassRequest.java:28)
at org.junit.internal.requests.MemoizingRequest.getRunner(MemoizingRequest.java:19)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:90)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:76)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:49)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:513)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Library I am using:
My Testrunner script is:
package TestRunner;
import org.junit.runner.RunWith;
import org.openqa.selenium.NoSuchElementException;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
#RunWith(Cucumber.class)
#CucumberOptions(features="C:\\Users\\Ashok Kumar\\eclipse-workspace\\CucumberWithSelenium\\Features",glue={"StepDefinition"})
public class Runner {
}
My steps script:
package StepDefinition;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.NoSuchElementException;
//import io.cucumber.java.*;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
//import cucumber.api.junit.Cucumber;
public class Steps {
WebDriver driver = null;
#Given("^I am on Facebook login page$")
/*
public void goToFacebook() {
WebDriver driver = new ChromeDriver();
driver.get("https://www.facebook.com");
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
} */
#Given("^Open the Chrome and launch the application$")
public void open_the_Chrome_and_launch_the_application() throws Throwable{
System.out.println("This Step open the Firefox and launch the application.");
}
#When("^Enter the Username and Password$")
public void enter_the_Username_and_Password() throws Throwable
{
System.out.println("This step enter the Username and Password on the login page.");
}
#Then("^Reset the credential$")
public void Reset_the_credential() throws Throwable
{
System.out.println("This step click on the Reset button.");
}
}
I have searched all previous posts in google on java.util.NoSuchElementException. But still I didn't come to webdriver as you have seen above. I did comment it as I have come across this error. I have tried even with WebDriver code above, still I am getting the error. Please help me. I am unable to edit java.base/java.util.ArrayList$Itr.next using next I have seen in google.
Thanks God. I found a solution or work around. Here is what I had done.
Had converted the project to Maven project.
I have mentioned latest dependencies
Here is my POM.
4.0.0
CucumberWithSelenium
CucumberWithSelenium
0.0.1-SNAPSHOT
src
maven-compiler-plugin
3.8.1
17
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.2.3</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>7.2.3</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-jvm-deps</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>net.masterthought</groupId>
<artifactId>cucumber-reporting</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>gherkin</artifactId>
<version>22.0.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-picocontainer -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>7.2.3</version>
</dependency>
</dependencies>

Maintaining the original traceId while passing messages through Kafka with quarkus and opentracing

I'm trying to create the most basic working example with two Quarkus (2.4.1.Final) microservices (a producer and a consumer) that communicate through Kafka and are traced with opentracing.
I have followed the kafka and the opentracing tutorial, ran the producer and consumer in dev mode (so they create that redpanda kafka broker), and then attempted to emit a POJO and log the traceId in both the consumer and producer. As far as I understand, this should work out of the box.
The POJO is sent, serialized and de-serialized without a hitch. The kafka message header that the consumer receives even has the correct original trace and span id injected into it (I've checked with debugging both the producer and consumer) using that uber-trace-id field.
But, for some reason, when logging the trace id, they don't match. It's like the tracing context "forgets" about the span it receives via kafka. Note that my business need is to just print the traceId every log so we can follow printed logs through kibana.
The producer:
package com.example;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.eclipse.microprofile.reactive.messaging.Channel;
import org.eclipse.microprofile.reactive.messaging.Emitter;
import org.jboss.logging.Logger;
#Path("/hello")
public class ExampleResource {
private static final Logger log = Logger.getLogger(ExampleResource.class);
private final Emitter<Person> peopleEmitter;
public ExampleResource(#Channel("people") Emitter<Person> peopleEmitter) {this.peopleEmitter = peopleEmitter;}
#GET
#Path("/{name}")
#Produces(MediaType.APPLICATION_JSON)
public Person hello(#PathParam("name") String name) {
var p = new Person();
p.name = name;
log.info("Produced " + p.name);
peopleEmitter.send(p);
return p;
}
}
The consumer:
package com.example;
import org.eclipse.microprofile.opentracing.Traced;
import org.eclipse.microprofile.reactive.messaging.Incoming;
import org.jboss.logging.Logger;
import javax.enterprise.context.ApplicationScoped;
#ApplicationScoped
public class PeopleConsumer {
private static final Logger log = Logger.getLogger(PeopleConsumer.class);
#Traced
#Incoming("people")
public void process(Person person) {
log.info("received " + person.name);
}
}
The POJO:
package com.example;
public class Person {
public String name;
}
App config for the producer:
quarkus.application.name=producer
quarkus.http.port=8090
quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, spanId=%X{spanId}, [%c{2.}] (%t) %s%e%n
mp.messaging.outgoing.people.connector=smallrye-kafka
mp.messaging.outgoing.people.interceptor.classes=io.opentracing.contrib.kafka.TracingProducerInterceptor
And the consumer:
quarkus.http.port=8091
quarkus.application.name=consumer
quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, spanId=%X{spanId}, [%c{2.}] (%t) %s%e%n
mp.messaging.incoming.people.connector=smallrye-kafka
mp.messaging.incoming.people.interceptor.classes=io.opentracing.contrib.kafka.TracingConsumerInterceptor
Serializer/deserializer
public class PersonDeserializer extends ObjectMapperDeserializer<Person> {
public PersonDeserializer() {
super(Person.class);
}
}
public class PersonSerializer extends ObjectMapperSerializer<Person> {
}
The dependencies (same for both):
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-opentracing</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-reactive-messaging-kafka</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-context-propagation</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-kafka-client</artifactId>
</dependency>
</dependencies>
Basic use case:
Put http://localhost:8090/hello/John into a browser. You will see log at the producer:
18:43:24 INFO traceId=00019292a43349df, spanId=19292a43349df, [co.ex.ExampleResource] (executor-thread-0) Produced John
And at the consumer
18:43:25 INFO traceId=1756e0a24c740fa6, spanId=1756e0a24c740fa6, [co.ex.PeopleConsumer] (pool-1-thread-1) received John
Notice the trace ids being different. I am not sure what else I'm supposed to be doing/configuring...

Quarkus with Vertx and RxJava2 imports yields NoClassDefFoundError

I'm attempting to follow the basic examples on quarkus.io regarding using Vert.x. While attempting to use RxJava instead of the Axle API, I get a runtime error:
Error handling 24416339-00a4-4898-8373-b5d905b39179-2, org.jboss.resteasy.spi.UnhandledException: java.lang.NoClassDefFoundError: Could not initialize class io.vertx.reactivex.ext.web.client.WebClient
My code for this class is as follows:
package io.blah.accountadminservice.client;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.eclipse.microprofile.config.inject.ConfigProperty;
//import io.vertx.axle.core.Vertx;
//import io.vertx.axle.ext.web.client.WebClient;
import io.vertx.reactivex.core.Vertx;
import io.vertx.reactivex.ext.web.client.WebClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#ApplicationScoped
public class VaultClient {
private static final Logger LOGGER = LoggerFactory.getLogger(VaultClient.class);
#Inject
Vertx vertx;
private WebClient client;
private String vaultToken;
#ConfigProperty(name = "vault.host")
private String vaultHost;
#ConfigProperty(name = "vault.port")
private String vaultPort;
#ConfigProperty(name = "vault.loginPath")
private String vaultLoginPath;
#PostConstruct
void initialize() {
this.client = WebClient.create(vertx); // this kills it
}
public void getVaultToken() {
}
}
When following the tutorial using the Axel API, I can build a web client. As soon switch to reactivex, these failures start happening.
My dependencies are:
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-rx-java2</artifactId>
<version>${vertx-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
vertx-version is set to 3.7.1 at the moment. Side note: I've noticed when using the rxjava2 import, it's not possible to import io.vertx.ext.web.client.WebClientOptions; I don't know if that's supposed to work or not.
You need to add the following dependency in your pom.xml file:
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-client</artifactId>
<version>3.7.1</version>
</dependency>
The version must match the version used in Quarkus.

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());