I am trying to create a RESTful web service in Karaf 4.0.8 with Apache CXF DOSGI. The service is being called but I am getting this error: No message body writer has been found for class....
Any suggestion is welcome. Thank you!!!
Component:
#Component(immediate = true, property = {
"service.exported.interfaces=*",
"service.exported.configs=org.apache.cxf.rs",
"org.apache.cxf.rs.provider=com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider",
"org.apache.cxf.rs.address=/integr" })
public class AccountRestService implements AccountWebUserIdResource {
...
}
Interface:
------------
#GET
#Produces({
"application/json"
})
AccountWebUserIdResource.GetAccountByWebUserIdResponse getAccountByWebUserId(
#PathParam("webUserId")
String webUserId,
#QueryParam("sc")
String sc,
#QueryParam("fields")
String fields)
throws Exception
;
Entity:
#JsonInclude(JsonInclude.Include.NON_NULL)
#Generated("org.jsonschema2pojo")
#JsonPropertyOrder({
"href",
"crm_member_id",
"email_address",
"account_status"
})
public class Account {
/**
*
* (Required)
*
*/
#JsonProperty("href")
private String href;
/**
*
* (Required)
*
*/
#JsonProperty("crm_member_id")
private String crmMemberId;
/**
*
* (Required)
*
*/
#JsonProperty("email_address")
private String emailAddress;
....
At least with CXF-DOSGi 2 your code probably will not work. Loading the provider from a class name is problematic in OSGi anyway as the CXF DOSGi code has no visibility of the com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider class.
In CXF-DOSGi this can be done using an intent. This is more OSGi friendly as the JacksonJsonProvider is then directly used as a class and so OSGi class loading works nicely. It is also necessary to set a bus property to all to override the jacksonprovider as the spec normally would not allow this.
cxf.bus.prop.skip.default.json.provider.registration=true
The intent class looks like this:
#Component(property = "org.apache.cxf.dosgi.IntentName=jackson")
public class JacksonIntent implements Callable<List<Object>> {
public List<Object> call() throws Exception {
return Arrays.asList((Object)new JacksonJaxbJsonProvider());
}
}
The intents provide a generic way to define features and other overrides for CXF without directly influencing your service class.
The intent then has to be referenced in the service using the service property service.exported.intents=jackson.
I just added a jackson example to CXF-DOSGi.
Another small obstacle is that the current cxf-jackson feature misses a bundle. See CXF-7298.
Related
I'd like to run Surefire in parallel mode (multiple JVMs) where each JVM must run:
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
exactly once before the first test. How can this be done?
There are various ways to make some code run at the beginning of a test suite.
Here are 4 (I'm sure there are more):
JUnit via RunWith Suite with Suite.SuiteClasses and BeforeClass (adapted from examples in SuiteTest):
#RunWith(Suite.class)
#SuiteClasses({FirstTest.class, SecondTest.class/*, ...*/, LastTest.class})
public static class AllWithSLF4JBridgeHandler {
#BeforeClass
public static void registerRootLoggerHandlers() {
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
}
}
TestNG with BeforeSuite:
/**
* Base class for each test class (i.e. every test class should extend this class).
*/
public abstract class BaseTest {
#BeforeSuite
public void registerRootLoggerHandlers() {
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
}
}
TestNG with Guice:
/**
* Test module. Each test class should be annotated with `#Guice(TestModule.class)`.
*/
public class TestModule implements Module {
#Override
public void configure(Binder binder) {
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
}
}
Static initialization blocks (test-framework independent):
/**
* Base class for each test class (i.e. every test class should extend this class).
*/
public abstract class BaseTest {
static {
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
}
}
I'm not sure how all of these methods work with Surefire's parallel mode. Methods 1 and 2 may not work there but I believe methods 3 and 4 should.
Another option would be to not use the programmatic installation of the SLF4JBridgeHandler but to use a java.util.logging.config file or class (see LogManager):
"java.util.logging.config.file":
logging.properties file:
// register SLF4JBridgeHandler as handler for the j.u.l. root logger
handlers = org.slf4j.bridge.SLF4JBridgeHandler
System property assignment:
java -Djava.util.logging.config.file=/path/to/logging.properties ...
This works well if you know the path to your logging file beforehand.
"java.util.logging.config.class":
Using a file may not be a good option if you're deploying a WAR and don't know where the file will be, etc. so alternatively you can create a logging config class:
public class SLF4JBridgeHandlerInitializer {
public SLF4JBridgeHandlerInitializer() throws IOException {
String loggingConfigurationString = "handlers = " + SLF4JBridgeHandler.class.getName();
InputStream inputStream = new ByteArrayInputStream(loggingConfigurationString.getBytes());
LogManager.getLogManager().readConfiguration(inputStream);
}
}
System property assignment:
java -Djava.util.logging.config.class=package.SLF4JBridgeHandlerInitializer ...
I've done this before and it has worked well for me (SLF4JBridgeHandler.Initializer by mfulton26 · Pull Request #57 · qos-ch/slf4j).
These final two options should initialize each JVM instance as long as the appropriate system property is set.
Most of my components are registered using the code-based (fluent) approach, but there is one particular component that I need to resolve differently at runtime. This is the interface and a couple of concrete implementations:-
public interface ICommsService ...
public class SerialCommsService : ICommsService ...
public class TcpCommsService : ICommsService ...
Some of our users will need the serial service while others will need the TCP service. My current solution (which works btw) is to use a typed factory and a custom component selector - the latter reads an app.config setting to determine which implementation the typed factory will resolve and return.
First the typed factory (nothing special about this):-
public interface ICommsServiceFactory
{
ICommsService Create();
void Release(ICommsService component);
}
Next, the custom component selector, which reads the fully-qualified type name from app.config (e.g. "MyApp.SomeNamespace.TcpCommsService"):-
public class CommsFactoryComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
return ConfigurationManager.AppSettings["commsServiceType"];
}
}
Then the registration stuff:-
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<ITypedFactoryComponentSelector>()
.ImplementedBy<CommsFactoryComponentSelector>());
container.Register(Component.For<ICommsFactory>()
.AsFactory(o => o.SelectedWith<CommsFactoryComponentSelector>()));
container.Register(Component.For<ICommsService>()
.ImplementedBy<SerialCommsService>().LifeStyle.Singleton);
container.Register(Component.For<ICommsService>()
.ImplementedBy<TcpCommsService>().LifeStyle.Singleton);
Finally, an example class with a dependency on ICommsService:-
public class Test
{
public Test(ICommsFactory commsFactory)
{
var commsService = commsFactory.Create();
...
}
}
As already mentioned, the above solution does work, but I don't like having to inject the factory. It would be more intuitive if I could just inject an ICommsService, and let something somewhere figure out which implementation to resolve and inject - similar to what I'm doing now but earlier in Windsor's "resolving pipeline". Is something like that possible?
You can use UsingFactoryMethod here:
container.Register(Component.For<ICommsService>().UsingFactoryMethod(kernel => kernel.Resolve<ICommsServiceFactory>().Create()));
You can inject ICommsService to any class now. ICommsServiceFactory can be a simple interface now:
interface ICommsServiceFactory
{
ICommsService Create();
}
Is there any way that I can use Jackson JSON Views or something like it, without having to annotate the original bean class? I'm looking for some kind of runtime/dynamic configuration to let me do something similar.
My bean is an #Entity packaged in a JAR that may be shared by multiple projects. I'm trying to avoid touching and re-packaging the shared JAR because of UI changes in the consuming projects.
Ideally I'd like to do something like
jsonViewBuilder = createViewBuilder(View.class);
jsonViewBuilder.addProperty("property1");
jsonViewBuilder.addProperty("property2");
to replace
Bean {
#JsonView(View.class)
String property1;
#JsonView(View.class)
String property2;
}
Any ideas?
Underlying environment: Spring 3.0, Spring MVC and Glassfish 3.1.1.
How about using the Mix-In feature?
http://wiki.fasterxml.com/JacksonMixInAnnotations
http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonView;
public class JacksonFoo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY)
.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);
mapper.getSerializationConfig().addMixInAnnotations(Bar.class, BarMixIn.class);
mapper.setSerializationConfig(mapper.getSerializationConfig().withView(Expose.class));
System.out.println(mapper.writeValueAsString(new Bar()));
// output: {"b":"B"}
}
}
class Bar
{
String a = "A";
String b = "B";
}
abstract class BarMixIn
{
#JsonView(Expose.class)
String b;
}
// Used only as JsonView marker.
// Could use any existing class, like Object, instead.
class Expose {}
I'm developing a web application running on Tomcat 6, with Flex as Frontend. I'm testing my backend with TestNG. Currently, I'm trying to test the following method in my Java-Backend:
public class UserDAO extends AbstractDAO {
(...)
public UserPE login(String mail, String password) {
UserPE dbuser = findUserByMail(mail);
if (dbuser == null || !dbuser.getPassword().equals(password))
throw new RuntimeException("Invalid username and/or password");
// Save logged in user
FlexSession session = FlexContext.getFlexSession();
session.setAttribute("user", dbuser);
return dbuser;
}
}
The method needs access to the FlexContext which only exists when i run it on the Servlet container (don't bother if you don't know Flex, it's more a Java-Mocking question in general). Otherwise i get a Nullpointer exception when calling session.setAttribute().
Unfortunately, I cannot set the FlexContext from outside, which would make me able to set it from my tests. It's just obtained inside the method.
What would be the best way to test this method with a Mocking framework, without changing the method or the class which includes the method? And which framework would be the easiest for this use case (there are hardly other things i have to mock in my app, it's pretty simple)?
Sorry I could try out all of them for myself and see how i could get this to work, but i hope that i'll get a quickstart with some good advices!
Obvious one approach is to re-factor it in a way that lets you inject things like the FlexContext. However this is not always possible. Some time ago a team I was part of hit a situation where we had to mock out some internal class stuff that we didn't have access to (like your context). We ended up using an api called jmockit which allows you to effective mock individual methods, including static calls.
Using this technology we where able to get around a very messy server implementation and rather than having to deploy to live servers and black box test, we were able to unit test at a fine level by overriding the server technology that was effective hard coded.
The only recommendation I would make about using something like jmockit is to ensure that in your test code there is clear documentation and seperation of jomockit from you main mocking framework (easymock or mockito would be my recommendations). Otherwise you risk confusing developers about the various responsibilities of each part of the puzzle, which usually leads to poor quality tests or tests that don't work that well. Ideally, as we ended up doing, wrap the jmockit code into you testing fixtures so the developers don't even know about it. Dealing with 1 api is enough for most people.
Just for the hell of it, here's the code we used to fix testing for an IBM class. WE basically need to do two things,
Have the ability to inject out own mocks to be returned by a method.
Kill off a constructor that went looking for a running server.
Do the above without having access to the source code.
Here's the code:
import java.util.HashMap;
import java.util.Map;
import mockit.Mock;
import mockit.MockClass;
import mockit.Mockit;
import com.ibm.ws.sca.internal.manager.impl.ServiceManagerImpl;
/**
* This class makes use of JMockit to inject it's own version of the
* locateService method into the IBM ServiceManager. It can then be used to
* return mock objects instead of the concrete implementations.
* <p>
* This is done because the IBM implementation of SCA hard codes the static
* methods which provide the component lookups and therefore there is no method
* (including reflection) that developers can use to use mocks instead.
* <p>
* Note: we also override the constructor because the default implementations
* also go after IBM setup which is not needed and will take a large amount of
* time.
*
* #see AbstractSCAUnitTest
*
* #author Derek Clarkson
* #version ${version}
*
*/
// We are going to inject code into the service manager.
#MockClass(realClass = ServiceManagerImpl.class)
public class ServiceManagerInterceptor {
/**
* How we access this interceptor's cache of objects.
*/
public static final ServiceManagerInterceptor INSTANCE = new ServiceManagerInterceptor();
/**
* Local map to store the registered services.
*/
private Map<String, Object> serviceRegistry = new HashMap<String, Object>();
/**
* Before runnin your test, make sure you call this method to start
* intercepting the calls to the service manager.
*
*/
public static void interceptServiceManagerCalls() {
Mockit.setUpMocks(INSTANCE);
}
/**
* Call to stop intercepting after your tests.
*/
public static void restoreServiceManagerCalls() {
Mockit.tearDownMocks();
}
/**
* Mock default constructor to stop extensive initialisation. Note the $init
* name which is a special JMockit name used to denote a constructor. Do not
* remove this or your tests will slow down or even crash out.
*/
#Mock
public void $init() {
// Do not remove!
}
/**
* Clears all registered mocks from the registry.
*
*/
public void clearRegistry() {
this.serviceRegistry.clear();
}
/**
* Override method which is injected into the ServiceManager class by
* JMockit. It's job is to intercept the call to the serviceManager's
* locateService() method and to return an object from our cache instead.
* <p>
* This is called from the code you are testing.
*
* #param referenceName
* the reference name of the service you are requesting.
* #return
*/
#Mock
public Object locateService(String referenceName) {
return serviceRegistry.get(referenceName);
}
/**
* Use this to store a reference to a service. usually this will be a
* reference to a mock object of some sort.
*
* #param referenceName
* the reference name you want the mocked service to be stored
* under. This should match the name used in the code being tested
* to request the service.
* #param serviceImpl
* this is the mocked implementation of the service.
*/
public void registerService(String referenceName, Object serviceImpl) {
serviceRegistry.put(referenceName, serviceImpl);
}
}
And here's the abstract class we used as a parent for tests.
public abstract class AbstractSCAUnitTest extends TestCase {
protected void setUp() throws Exception {
super.setUp();
ServiceManagerInterceptor.INSTANCE.clearRegistry();
ServiceManagerInterceptor.interceptServiceManagerCalls();
}
protected void tearDown() throws Exception {
ServiceManagerInterceptor.restoreServiceManagerCalls();
super.tearDown();
}
}
Thanks to Derek Clarkson, I successfully mocked the FlexContext, making the login testable. Unfortunately, it's only possible with JUnit, as far as i see (tested all versions of TestNG with no success - the JMockit javaagent does not like TestNG, See this and this issues).
So this is how i'm doing it now:
public class MockTests {
#MockClass(realClass = FlexContext.class)
public static class MockFlexContext {
#Mock
public FlexSession getFlexSession() {
System.out.println("I'm a Mock FlexContext.");
return new FlexSession() {
#Override
public boolean isPushSupported() {
return false;
}
#Override
public String getId() {
return null;
}
};
}
}
#BeforeClass
public static void setUpBeforeClass() throws Exception {
Mockit.setUpMocks(MockFlexContext.class);
// Test user is registered here
(...)
}
#Test
public void testLoginUser() {
UserDAO userDAO = new UserDAO();
assertEquals(userDAO.getUserList().size(), 1);
// no NPE here
userDAO.login("asdf#asdf.de", "asdfasdf");
}
}
For further testing i now have to implement things like the session map myself. But thats okay as my app and my test cases are pretty simple.
I have a Struts2 Action Class configured via annotations. All of the "normal" methods that are annotated with #Action work fine.
However, I need to add a method into the action that returns JSON.
Here is a trimmed down version of my class (dao autowired with Spring):
#Namespace("featureClass")
// define success and input actions for class here
public class FeatureClassAction extends ActionSupport {
FeatureClassDao featureClassDao;
#Autowired
public setFeatureClassDao(FeatureClassDeao featureClassDao) {
this.featureClassDao = featureClassDao;
}
List<FeatureClass> featureClasses;
// snip normal actions
#Action("/featureClassesJSON")
#JSON
public String getFeatureClassesJSON() throws Exception {
featureClasses = featureClassDao.getAll();
return SUCCESS;
}
}
Can anyone assist? If I have to go the struts.xml route, that means moving all of my other actions (which work fine) into it.
I figured I would share the answer, since anyone else with the same problem would likely also face the silence.
I created two actions: FeatureClassAction and FeatureClassJsonAction. FeatureClassAction was annotated as such:
#ParentPackage("struts-default")
#Namespace("/featureClass")
public class FeatureClassAction extends ActionSupport {
FeatureClassJsonAction is annotated like this:
#ParentPackage("json-default")
#Namespace("/featureClass")
public class FeatureClassJsonAction extends ActionSupport {
The method in the JSON Action was annotated like this:
#Action(value="featureClassesJson", results = {
#Result(name="success", type="json")
})
public String getFeatureClassesJSON() throws Exception {
Hope it helps someone.