force glassfish 4 to use jackson 2.3 - glassfish

I wrote an maven application which should run on Glassfish 4.
The Standard ApplicationConfig looks like this:
#javax.ws.rs.ApplicationPath("resources")
public class ApplicationConfig extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
// following code can be used to customize Jersey 2.0 JSON provider:
try {
Class jsonProvider = Class.forName("org.glassfish.jersey.jackson.JacksonFeature");
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
addRestResourceClasses(resources);
return resources;
}
The problem now is, that my resources which generate Json should use jackson 2.3 annotations.
But my glassfish uses some codehaus. ... packages to provide json. codehaus is the old version of jackson. I want to use the new one from fasterxml which provides the #JsonIdentityInfo annotation.
I thought that i could solve my problem by writing:
#javax.ws.rs.ApplicationPath("resources")
public class ApplicationConfig extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
resources.add(JacksonFeatures.class); //from the com.fasterxml.jackson.jaxrs.annotation Package
resources.add(JacksonJaxbJsonProvider.class);
resources.add(JacksonJsonProvider.class);
addRestResourceClasses(resources);
return resources;
}
But no effect. Now Glassfish uses the standard JsonProvider Moxy... which i dont want to use. Do you have any tips how i can force glassfish to use my library instead of the buildin-libraries? Or can i change the buildin library to the newer one?
And if you know how to solve this. could you please provide a little code-snippet?
EDIT 1:
After trying the first approach to solve it:
new ApplicationConfig:
#javax.ws.rs.ApplicationPath("resources")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
//register( new GZipEncoder() );
register( JacksonFeature.class );
}
private void addMyResources() {
//a lot of resources.
}
}
JacksonFeature:
public class JacksonFeature implements Feature {
public boolean configure( final FeatureContext context ) {
String postfix = '.' + context.getConfiguration().getRuntimeType().name().toLowerCase();
context.property( CommonProperties.MOXY_JSON_FEATURE_DISABLE + postfix, true );
context.register( JsonParseExceptionMapper.class );
context.register( JsonMappingExceptionMapper.class );
context.register( JacksonJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class );
return true;
}
}
pom:
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.4</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.4</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
</dependency>
</dependencies>
Dependencies:
http://i.stack.imgur.com/uA4V2.png
Error:
SEVERE: Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [Ref<ContainerRequest>] with qualifiers [#Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] #Inject org.glassfish.jersey.server.internal.routing.UriRoutingContext(Ref<ContainerRequest>, ProcessingProviders)]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Ref<ContainerRequest>] with qualifiers [#Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] #Inject org.glassfish.jersey.server.internal.routing.UriRoutingContext(Ref<ContainerRequest>, ProcessingProviders)]
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:403)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:325)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:177)
...
or
SEVERE: Exception while loading the app
SEVERE: Undeployment failed for context /blueserver
INFO: file:/C:/bluetrail/blueserver/target/blueserver-0.0.0.1/WEB-INF/classes/_de.bluetrail_blueserver_war_0.0.0.1PU logout successful
SEVERE: Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [IterableProvider<InjectionResolver<Object>>] with qualifiers [#Default] at injection point [[BackedAnnotatedParameter] Parameter 2 of [BackedAnnotatedConstructor] #Inject org.glassfish.jersey.internal.inject.JerseyClassAnalyzer(#Named ClassAnalyzer, IterableProvider<InjectionResolver<Object>>)]
EDIT 2:
i will now post some classes of my project. In that classes i included all Annotations that i use.
i have like 16 entities like that:
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
#Entity
#JsonIdentityInfo(generator = ObjectIdGenerators.None.class, property = "id", scope=Address.class)
//the JsonIdentityInfo is the reason i need Jackson 2
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String postalCode;
private String city;
private String country;
private String street;
private String houseNumber;
#Embedded
private Coordinate coordinate;
//getters, setters , etc.
}
then i have a lot of DAO's like that:
import de.ibs.trail.entity.Address;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
#Stateless
public class AddressDao extends GenericDao {
public Address getAddress(long id){
return em.find(Address.class, id);
}
public List<Address> getAddresses(){
List<Address> address = em.createQuery("SELECT a FROM Address a", Address.class).getResultList();
return address;
}
}
and finally i have a lot of REssources like that:
import de.bluetrail.blueserver.dao.AddressDao;
import de.ibs.trail.entity.Address;
import java.util.List;
import javax.ejb.Stateless;
import javax.inject.Inject;
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.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
#Path("dummy")
#Stateless
public class DummyResource {
#Context
private UriInfo context;
#Inject userAuth user;
#Inject addressDao AddressDao;
public DummyResource() {
}
#GET
#Produces("application/json")
public List<Address> getAddress() {
return AddressDao.getAddresses();
}
}
Thats the first part. As a second part i have a class for some Google Services. Because i want to try to use some Google GeoLocation and Routing. I put the Google-Code into a pasteBin file, because its so huge:
http://pastebin.com/u3e0dms6
there i use libraries like:
import com.fasterxml.jackson.databind.ObjectMapper;
import de.ibs.trail.entity.Address;
//some other entities
//...
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Set;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
I hope that helps. All the other classes use the same annotations.

First make sure you have the following in your pom.xml:
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
</dependency>
Then make sure you DO NOT have this in any pom.xml:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.5</version>
</dependency>
Then you need to disable moxy. The easiest way to do this is to ditch your Application class and replace is with a ResourceConfig class. First lets create YOUR JacksonFeature class:
public class JacksonFeature implements Feature {
public boolean configure( final FeatureContext context ) {
String postfix = '.' + context.getConfiguration().getRuntimeType().name().toLowerCase();
context.property( CommonProperties.MOXY_JSON_FEATURE_DISABLE + postfix, true );
context.register( JsonParseExceptionMapper.class );
context.register( JsonMappingExceptionMapper.class );
context.register( JacksonJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class );
return true;
}
}
Two interesting things here, first I disabled moxy and second I made sure to add the JacksonException mappers. This way you will get better errors than internal server error if there is a parsing or generation exception. Okay, last step it so rewrite your Application as a ResourceConfig class:
#javax.ws.rs.ApplicationPath("resources")
public class RestApplication extends ResourceConfig {
public RestApplication() {
register( new GZipEncoder() );
register( JacksonFeature.class );
}
private void addMyResources() {
register( MyResource1.class );
register( MyResource2.class );
}
}
That should do it. Also, instead of registering the resources one by one like this, if you know their path you can just remove all that code and add this to the constructor of RestApplication:
package( "com.me.myrestresourcespackage" );
Hope this helps.

Related

Spring Cloud Contract EXPLICIT and WEBTESTCLIENT testMode

I want to use Spring Cloud Contract to produce my contracts and verify them. I want to use Spring WebFlux and Junit5. This is my Controller:
#RestController
#Slf4j
public class HelloWorldPortRESTAdapter implements HelloWorldPort {
#GetMapping(value = "/hello-world", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
#Override
public Mono<String> helloWorld() {
return Mono.just("Hello World!");
}
}
This is cloud contract maven plugin configuration:
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<basePackageForTests>com.example.feedproviderapi.contract</basePackageForTests>
<testFramework>JUNIT5</testFramework>
<testMode>EXPLICIT</testMode>
</configuration>
</plugin>
But i don't know how base test class should look like. I tried this:
#ExtendWith(SpringExtension.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class BaseTestClass {
#LocalServerPort
private int port;
#BeforeEach
void setup(){
RestAssured.baseURI = "http://localhost:" + this.port;
}
}
When I run mvn clean install, it returns java.net.ConnectException: Connection refused (Connection refused)
Then I changed testMode property in maven plugin to WEBTESTCLIENT and updated BaseTestClass like this:
#ExtendWith(SpringExtension.class)
#SpringBootTest
public class BaseTestClass {
#Autowired
WebApplicationContext context;
#BeforeEach
void setup(){
RestAssuredWebTestClient.standaloneSetup(context);
}
}
And again when I run mvn clean install now it returns:
You haven't configured a WebTestClient instance. You can do this statically
RestAssuredWebTestClient.mockMvc(..)
RestAssuredWebTestClient.standaloneSetup(..);
RestAssuredWebTestClient.webAppContextSetup(..);
or using the DSL:
given().
mockMvc(..). ..
Btw I tried RestAssuredWebTestClient.standaloneSetup(new HelloWorldPortRESTAdapter()); as well in my BaseTestClass but the result is same.
So how should I implement BaseTestClass regarding EXPLICIT and WEBTESTCLIENT testModes?
I have struggled for 3 days, to makes RestAssuredWebTestClient works.
Thanks a llooottt for : https://www.baeldung.com/spring-5-webclient
That's how i could do that:
#WebFluxTest
public class AnimeControllerIntegrTest{
WebTestClient testClient;
#Test
public void get_RA() {
testClient = WebTestClient.bindToServer().baseUrl("http://localhost:8080/animes").build();
RestAssuredWebTestClient
.given()
.webTestClient(testClient)
.when()
.get()
.then()
.statusCode(OK.value())
.body("name" ,hasItem("paulo"))
;
}
}
Please check the spring cloud contract samples https://github.com/spring-cloud-samples/spring-cloud-contract-samples/blob/master/producer_webflux_webtestclient
And junit5
https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/producer_with_junit5
The
plugin
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>${spring-cloud-contract.version}</version>
<extensions>true</extensions>
<configuration>
<packageWithBaseClasses>com.example</packageWithBaseClasses>
<testMode>WEBTESTCLIENT</testMode>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<failIfNoTests>true</failIfNoTests>
</configuration>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>${junit-platform-surefire-provider.version}</version>
</dependency>
</dependencies>
</plugin>
And The base class for junit5
public abstract class BeerRestBase {
#BeforeEach
public void setup() {
// remove::start[]
RestAssuredWebTestClient.standaloneSetup(new ProducerController(personToCheck -> personToCheck.age >= 20));
// remove::end[]
}
}
Try passing an ApplicationContext instance instead of WebApplicationContext.

JAX-RS #EJB injection gives NullPointerException

I'm trying to deploy a war file to run on WildFly Swarm. While doing a GET request, a NullPointerException occurs because an injection fails and the reference is, obviously, null.
SomeDao.java
import java.util.List;
import java.util.UUID;
import javax.ejb.Local;
#Local
public interface SomeDao {
public List<MyEntity> listAll();
public void store(MyEntity entity);
}
SpecializedDao.java
import java.util.List;
import java.util.UUID;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
#Stateless
public class SpecializedDao implements SomeDao {
#PersistenceContext(unitName="primary")
protected EntityManager entityManager;
public SpecializedDao() {}
#Override
public List<MyEntity> listAll() {
return this.entityManager
.createQuery("SELECT entity FROM MyEntity entity", MyEntity.class)
.getResultList();
}
#Override
public void store(MyEntity entity) {
entityManager.getTransaction().begin();
entityManager.persist(entity);
entityManager.getTransaction().commit();
}
}
Then, there's the endpoint where I need to inject a SpecializedDao instance.
MyEndpoint.java
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Stateless
#Path("/something")
public class MyEndpoint {
#EJB
private SomeDao dao;
#GET
#Path("/test")
#Produces({MediaType.APPLICATION_JSON})
public Response test() {
MyEntity testEntity = new MyEntity("something", "something");
dao.store(testEntity);
return Response.ok("All done!").build();
}
}
beans.xml
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.2" bean-discovery-mode="annotated">
</beans>
The NullPointerException is launched at dao.store(testEntity), because dao references a null object. I'm pretty sure the persistence.xml file is correct because the EntityManager works on another test case, so I think the problem is at injection.
Where did I do something wrong?
Other things you can check.
Is your beans.xml located in the correct folder (ie in WEB-INF in case of a webapp/war) ?
Did you include the Swarm CDI fraction/dependency (org.wildfly.swarm:cdi) ?
I'm not a Swarm expert but it may be that the CDI fraction only works when beans are injected "à la JSR-299" that is using java.inject.#Inject (rather than using #EJB).
#Inject
private SomeDao dao;
Ultimately: try with bean-discovery-mode="all" in beans.xml (...even though "annotated" seems correct)
Didn't you forget to put a "beans.xml" file (under WEB-INF/META-INF folder) ?

How to return custom Key value pair from spring-cloud-config-server?

I am using spring-cloud-config-server , I do not want Git backend or file system based backend . I want custom Key value pair to be returned.
I found solution of this .
1) on the application.properties set spring.profiles.active=native
2) Create CustomEnvironmentRepository -- Refer code on #A
3) Register CustomEnvironmentRepository Bean -- Refer code on #B
#A -
import java.util.HashMap;
import java.util.Map;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.PropertySource;
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
import org.springframework.core.Ordered;
public class CustomEnvironmentRepository implements
EnvironmentRepository, Ordered
{
#Override
public Environment findOne(String application, String profile, String label)
{
Environment environment = new Environment(application, profile);
final Map<String, String> properties = new HashMap<>();
properties.put("mycustomPropertyKey", "myValue");
environment.add(new PropertySource("mapPropertySource", properties));
return environment;
}
#Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
#B
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
import org.springframework.context.annotation.Bean;
#EnableConfigServer
#SpringBootApplication
public class MyCloudConfigApplication {
public static void main(String[] args) {
SpringApplication.run(MyCloudConfigApplication.class, args);
}
#Bean
public EnvironmentRepository environmentRepository() {
return new CustomEnvironmentRepository();
}
}
Test by invoking - http://localhost:9092/my-cloud-config.properties
You will see
mycustomPropertyKey: myValue
My Original Goal is to set some properties from Azure Key Vault , I guess integrating AzureKey Vault in CustomEnvironmentRepository , I should be able to achieve this
Application Properties File will look like
server.port=<YOUR_PORT>
spring.profiles.active=native
azure.keyvault.uri=<YOUR_AZURE_URI_CAN_BE_FOUND_IN_AZURE_PORTAL>
azure.keyvault.client-id=<YOUR_AZURE_CLIENT_ID_CAN_BE_FOUND_IN_AZURE_PORTAL>
azure.keyvault.client-key=<YOUR_AZURE_CLIENT_KEY_CAN_BE_FOUND_IN_AZURE_PORTAL>
IN POM Use these Dependencies
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-keyvault-secrets-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>

spring boot application configuration for JaxRs based Swagger

Is there an example available to configure spring boot+Jersey+JaxRs application for Swagger?
Referring to this post, I have below code in my app and am not able to bring up the swagger UI and neither able to list the resources using
http://localhost:8080/api/root/{funcId}/entities
.
ApplicationInitializer class: (Groovy)
#Configuration
#EnableAutoConfiguration
class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run( Application.class, args)
}
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources( Application, "classpath:/META-INF/com/company/automation/functionality/bootstrap.xml");
}
#Bean
ServletRegistrationBean jerseyServlet() {
ServletRegistrationBean registration = new ServletRegistrationBean(new SpringServlet());
Map params = ["com.sun.jersey.config.property.packages":"com.company.automation.functionality.impl;com.wordnik.swagger.jersey.listing"]
registration.setInitParameters(params)
return registration;
}
#Bean
ServletRegistrationBean jerseyJaxrsConfig() {
ServletRegistrationBean registration = new ServletRegistrationBean(new JerseyJaxrsConfig());
Map params = ["swagger.api.basepath":"http://localhost:8080/api", "api.version":"1.0"]
registration.setInitParameters(params)
return registration;
}
}
Resource:
#Component
#Path('root/{funcId}/entities')
#Api (value = "root/{funcId}/entities", description = "Operations about entity Details")
#CompileStatic
class EntityDetailsResource {
..
}
[EDIT]. I am using Jersey 1.16 and can not use Jersey 2 due to application impact
I was able to get it working, but I'm not sure how good the Spring support is in Jersey 1.x, so I did it with 2.7 (that link you posted is for JAX-RS 1.x). This worked:
#Configuration
#ComponentScan
#EnableAutoConfiguration
#Path("/")
#Api(value = "home", description = "Demo API")
public class Application extends ResourceConfig implements CommandLineRunner {
#GET
#ApiOperation(value = "Get Greeting", notes = "Returns greeting")
public String home() {
return "Hello";
}
#Override
public void run(String... args) throws Exception {
SwaggerConfig config = ConfigFactory.config();
config.setBasePath("http://localhost:8080/");
config.setApiVersion("1.0.0");
ScannerFactory.setScanner(new DefaultJaxrsScanner());
ClassReaders.setReader(new JerseyApiReader());
}
public Application() {
register(Application.class);
packages("com.wordnik.swagger.jersey.listing");
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
It uses spring-boot-jersey, which is experimental, to create the Jersey servlet, but you can do that easily with a ServletRegistration #Bean if you want to stick to vanilla Boot.
I had to pin the Jersey versions and add some exclusions. Here are my dedendencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jersey2-jaxrs_2.10</artifactId>
<version>1.3.2</version>
<exclusions>
<exclusion>
<artifactId>jsr311-api</artifactId>
<groupId>javax.ws.rs</groupId>
</exclusion>
</exclusions>
</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-servlet</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-jersey</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
</dependencies>
Here's an example Spring Boot app that uses Jersey 2: http://raibledesigns.com/rd/entry/a_webapp_makeover_with_spring

WELD-001408 Unsatisfied dependencies for type [Logger] with qualifiers [#Default] at injection point [[field] using arquillian

I am running a basic arquillian unit test, using the Greeter example on the arquillian site. The only difference is that am doing a log.debug in the greet(PrintStream to, String name) function in Greeter.java. Am using slf4j for logging.
Greeter.java
package org.arquillian.example;
import java.io.PrintStream;
import javax.inject.Inject;
import org.slf4j.Logger;
public class Greeter {
#Inject
private Logger log;
public void greet(PrintStream to, String name) {
log.debug("Greeter Testing");
to.println(createGreeting(name));
}
public String createGreeting(String name) {
return "Hello, " + name + "!";
}
}
GreeterTest.java
package org.arquillian.example;
import javax.inject.Inject;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(Arquillian.class)
public class GreeterTest {
#Inject
Greeter greeter;
#Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClass(Greeter.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
#Test
public void should_create_greeting() {
Assert.assertEquals("Hello, Earthling!",
greeter.createGreeting("Earthling"));
greeter.greet(System.out, "Earthling");
}
}
Am getting WELD-001408 Unsatisfied dependencies for type [Logger] with qualifiers [#Default] at injection point [[field] #Inject private org.arquillian.example.Greeter.log] error when running the test. Can someone please help on this?
This is a CDI issue. You don't have a producer for your Logger in the first place.
Secondly, any such producer should be added to the ShrinkWrap deployment.
A producer for the Logger is usually written as such:
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SLF4JProducer {
#Produces
public Logger producer(InjectionPoint ip){
return LoggerFactory.getLogger(
ip.getMember().getDeclaringClass().getName());
}
}
This producer receives an injection point and proceeds to return a SLF4J Logger instance. The instance has the same name as the class containing the injection point.
also change in bean.xml bean-discovery-mode to all
bean-discovery-mode="all"
Instead of injecting Logger, it worked just fine for me when I used LoggerFactory.
private Logger log = LoggerFactory.getLogger(Greeter.class);
In my case I must provide the injections programmatically
Import:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Initialization
private Logger logger;
#Inject
public LoggingInterceptor() {
logger = LoggerFactory.getLogger(LoggingInterceptor.class);
}