Class xxx does not contain a public constructor needed to autobuild when xxx become a Tapestry Service - resteasy

I'm discovering the wonderful integration work made by Tynamo's team between Tapestry and Resteasy .
I'm trying to activate Liveclass Reloading on webservices. As per doc says :
Documentation
The only thing you need to do to enable live class reloading for your
REST services is to bind them as regular Tapestry IoC services and
contribute them to javax.ws.rs.core.Application.class. Read more about
how service implementation reloading works in:
http://tapestry.apache.org/reload.html
Here is an example from the tapestry-resteasy test suite.
public static void bind(ServiceBinder binder)
{
binder.bind(ReloadableEchoResource.class, ReloadableEchoResourceImpl.class);
}
#Contribute(javax.ws.rs.core.Application.class)
public static void configureRestResources(Configuration<Object> singletons, ReloadableEchoResource reloadableEchoResource)
{
singletons.add(reloadableEchoResource);
}
My Own Work
This is exactly what I'm doing (well ... hmmm at least I believe that it is ;D):
My binding
public static void bind(ServiceBinder binder)
{
binder.bind(PushMessageService.class, GCMPushMessageServiceImpl.class);
binder.bind(UserService.class, HibernateUserServiceImpl.class);
binder.bind(IUserResource.class, UserResourceImpl.class);
}
/**
* Contributions to the RESTeasy main Application, insert all your RESTeasy singletons services here.
*/
#Contribute(javax.ws.rs.core.Application.class)
public static void configureRestResources(Configuration<Object> singletons, IUserResource userResource)
{
singletons.add(userResource);
}
My Interface
#Path("/user")
public interface IUserResource {
/**
* Lecture de tous les utilisateurs
*
* #return une List des utilisateurs existants
*/
#GET
#Produces("application/json")
public abstract List<User> getAllDomains();
Error
But when I start my app, I obtain this message :
HTTP ERROR 500
Problem accessing /user. Reason:
Exception constructing service 'ResteasyRequestFilter': Error building service proxy for service 'Application' (at org.tynamo.resteasy.Application(Collection) (at Application.java:14) via org.tynamo.resteasy.ResteasyModule.bind(ServiceBinder) (at ResteasyModule.java:31)): Error invoking service contribution method org.tynamo.resteasy.ResteasyModule.javaxWsRsCoreApplication(Configuration, ObjectLocator, ResteasyPackageManager, ClassNameLocator): Class com.sopragroup.ecommerce.mobile.rest.IUserResource does not contain a public constructor needed to autobuild.
Caused by:
java.lang.RuntimeException: Exception constructing service 'ResteasyRequestFilter': Error building service proxy for service 'Application' (at org.tynamo.resteasy.Application(Collection) (at Application.java:14) via org.tynamo.resteasy.ResteasyModule.bind(ServiceBinder) (at ResteasyModule.java:31)): Error invoking service contribution method org.tynamo.resteasy.ResteasyModule.javaxWsRsCoreApplication(Configuration, ObjectLocator, ResteasyPackageManager, ClassNameLocator): Class com.sopragroup.ecommerce.mobile.rest.IUserResource does not contain a public constructor needed to autobuild.
at org.apache.tapestry5.ioc.internal.services.JustInTimeObjectCreator.obtainObjectFromCreator(JustInTimeObjectCreator.java:75)
at org.apache.tapestry5.ioc.internal.services.JustInTimeObjectCreator.createObject(JustInTimeObjectCreator.java:54)
It's quite like the autobinding don't works (indeed I do think it is).
Obviously, when I try to without creating an interface and binding, it works like a charm.
Can someone give me a clue ?

I think the issue is that tapestry-resteasy is trying to autobuild IUserResource because it's in the "rest" package.
Here is a very important documentation line that you may have missed:
One more thing: DO NOT put this service in the autodiscovery package.
This is an important line and it was somehow hidden in the docs so I added a warning to make it more visible for future users: http://docs.codehaus.org/pages/diffpagesbyversion.action?pageId=151847035&selectedPageVersions=24&selectedPageVersions=23

Related

Static Analysis tool to catch self-invocation bypassing Spring cache #Cacheable method

I understand that this is because of the way proxies are created for handling caching, transaction related functionality in Spring. And the way to fix it is use AspectJ but I donot want to take that route cause it has its own problems. Can I detect self-invocation using any static analyis tools?
#Cacheable(value = "defaultCache", key = "#id")
public Person findPerson(int id) {
return getSession().getPerson(id);
}
public List<Person> findPersons(int[] ids) {
List<Person> list = new ArrayList<Person>();
for (int id : ids) {
list.add(findPerson(id));
}
return list;
}
If it would be sufficient for you to detect internal calls, you could use native AspectJ instead of Spring AOP for that and then throw runtime exceptions or log warnings every time this happens. That is not static analysis, but better than nothing. On the other hand, if you use native AspectJ, you are not limited to Spring proxies anyway and the aspects would work for self-invocation too.
Anyway, here is what an aspect would look like, including an MCVE showing how it works. I did it outside of Spring, which is why I am using a surrogate #Component annotation for demo purposes.
Update: Sorry for targeting #Component classes instead of #Cacheable classes/methods, but basically the same general approach I am showing here would work in your specific case, too, if you simply adjust the pointcut a bit.
Component annotation:
package de.scrum_master.app;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
#Retention(RUNTIME)
#Target(TYPE)
public #interface Component {}
Sample classes (components and non-components):
This component is to be called by other components should not lead to exceptions/warnings:
package de.scrum_master.app;
#Component
public class AnotherComponent {
public void doSomething() {
System.out.println("Doing something in another component");
}
}
This class is not a #Component, so the aspect should ignore self-invocation inside it:
package de.scrum_master.app;
public class NotAComponent {
public void doSomething() {
System.out.println("Doing something in non-component");
new AnotherComponent().doSomething();
internallyCalled("foo");
}
public int internallyCalled(String text ) {
return 11;
}
}
This class is a #Component. The aspect should flag internallyCalled("foo"), but not new AnotherComponent().doSomething().
package de.scrum_master.app;
#Component
public class AComponent {
public void doSomething() {
System.out.println("Doing something in component");
new AnotherComponent().doSomething();
internallyCalled("foo");
}
public int internallyCalled(String text ) {
return 11;
}
}
Driver application:
Please note that I am creating component instances throughout this sample code with new instead of requesting beans from the application context, like I would do in Spring. But you can ignore that, it is just an example.
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
new NotAComponent().doSomething();
new AComponent().doSomething();
}
}
Console log when running without aspect:
Doing something in non-component
Doing something in another component
Doing something in component
Doing something in another component
Now with the aspect, instead of the last message we would expect an exception or a logged warning. Here is how to do that:
Aspect:
Sorry for using native AspectJ syntax here. Of course, you could also use annotation-based syntax.
package de.scrum_master.aspect;
import de.scrum_master.app.*;
public aspect SelfInvocationInterceptor {
Object around(Object caller, Object callee) :
#within(Component) &&
call(* (#Component *).*(..)) &&
this(caller) &&
target(callee)
{
if (caller == callee)
throw new RuntimeException(
"Self-invocation in component detected from " + thisEnclosingJoinPointStaticPart.getSignature() +
" to "+ thisJoinPointStaticPart.getSignature()
);
return proceed(caller, callee);
}
}
Console log when running with aspect:
Doing something in non-component
Doing something in another component
Doing something in component
Doing something in another component
Exception in thread "main" java.lang.RuntimeException: Self-invocation in component detected from void de.scrum_master.app.AComponent.doSomething() to int de.scrum_master.app.AComponent.internallyCalled(String)
at de.scrum_master.app.AComponent.internallyCalled_aroundBody3$advice(AComponent.java:8)
at de.scrum_master.app.AComponent.doSomething(AComponent.java:8)
at de.scrum_master.app.Application.main(Application.java:6)
I think, you can use this solution and maybe rather log warnings instead of throwing exceptions in order to softly guide your co-workers to inspect and improve their AOP-dependent Spring components. Sometimes maybe they do not wish self-invocation to trigger an aspect anyway, it depends on the situation. You could run the Spring application in full AspectJ mode and then, after evaluating the logs, switch back to Spring AOP. But maybe it would be simpler to just use native AspectJ to begin with and avoid the self-invocation problem altogether.
Update: In AspectJ you can also make the compiler throw warnings or errors if certain conditions are met. In this case you could only statically determine calls from components to other components, but without differentiating between self-invocation and calls on other methods from other components. So this does not help you here.
Please also notice that this solution is limited to classes annotated by #Component. If your Spring bean is instantiated in other ways, e.g. via XML configuration or #Bean factory method, this simple aspect does not work. But it could easily be extended by checking if the intercepted class is a proxy instance and only then decide to flag self-invocations. Then unfortunately, you would have to weave the aspect code into all of your application classes because the check can only happen during runtime.
I could explain many more things, such as using self-injection and call internal methods on the injected proxy instance instead of via this.internallyCalled(..). Then the self-invocation problem would be solved too and this approach also works in Spring AOP.
Can I detect self-invocation using any static analysis tools?
In theory you can, but be aware of Rice's theorem. Any such tool would sometimes give false alarms.
You could develop such a tool using abstract interpretation techniques. You may need more than a year of work.
You could subcontract the development of such tools to e.g. the Frama-C team. Then email me to basile.starynkevitch#cea.fr

Spring Controller sometimes has null #Autowired objects and seems not to be managed by Spring Context

I have a Spring controller defined like this with 2 request mappings, one using localDAO and the other using dependencyDAO. LocalDAO classes exist in my project and DependencyDAO classes are imported via maven dependency:
#RestController
#PreAuthorize("hasRole('USER')")
public class MyController
#Autowired
private localDAO LocalDAO; // dao classes exist in my project
#Autowired
private DependencyDAO dependencyDAO; // dao classes imported via maven dependency
...
#RequestMapping("/getUsingLocalDAO")
private String getUsingLocalDAO(
#JsonProperty("param") String param) {
localDAO.get(param) ... // <== this never null
}
#RequestMapping("/getUsingDependencyDAO")
private String getUsingDependencyDAO(
#JsonProperty("param") String param) {
dependencyDAO.get(param) ... // <== this always null
}
...
My dao beans are defined in another class:
#Configuration
public class DaoBeans {
#Bean
public LocalDAO localDAO() throws Exception {
return new LocalDAOImpl();
}
#Bean
public DependencyDAO dependencyDAO () throws Exception {
return new DependencyDAOImpl();
}
...
I am doing an $http.post from Angular like this:
$http.post('getUsingLocalDAO', $.param($scope.parameters), {
headers : {
"content-type" : "application/x-www-form-urlencoded"
}
}).success(function(data) {
...
}).error(function(data) {
...
$http.post('getUsingDependencyDAO', $.param($scope.parameters), {
headers : {
"content-type" : "application/x-www-form-urlencoded"
}
}).success(function(data) {
...
}).error(function(data) {
...
Both posts are identical except for the method they execute.
When stepping through the debugger I can see all the dao beans being created.
When I call getUsingLocalDAO everything works as expected.
But, when I call getUsingDependencyDAO every #Autowired object is null.
I believe I am getting different instances of MyController. One managed by Spring and one not; or at least not instantiated properly.
I make these calls in succession. It doesn't matter what order they are in.
I tried injecting the servlet context via #Autowired to get the bean manually but it is always null in getUsingDependencyDAO as well.
I tried using application context aware and although I see the context setter being set in the debugger the context is always null in getUsingDependencyDAO.
If I wrap the two calls in a third request mapping like so everything works well (no null objects).
#RequestMapping("/getUsingBothDAO")
private String getUsingBothDAO(
#JsonProperty("param") String param) {
getLocalDAO(param);
getDependencyDAO(param);
...
}
I am using Spring-Boot 4.1.5. My project is 100% annotation driven and has no .xml configurations. The only difference between the two request mappings is that one uses a bean from a dependency and one does not.
I have been searching for an answer to this problem for 3 days and have not found anything close to what I am experiencing.
Can anyone shed some light as to what I am doing wrong? Any help would be greatly appreciated.
Thanks.
Ok, I solved the problem. My example code above is not entirely accurate. The request method that was giving me nulls was defined as a private method while the one that worked was defined as public as its supposed to be. Originally the private method was not a request method and that modifier remained after the change. I changed it to public and everything is working.
It was just coincidence that the private method was from an imported project. It's curious that Spring did not throw an error that the request mapping didn't exist on the private method or something to that effect.
Thanks to anyone who looked at this and was trying to figure it out.

WCF RIA Services DomainService error: ContractDescription has zero operations; a contract must have at least one operation

I am developing a small instant messaging application that makes use of few DomainServices on the server side. Trying to access the domain service URL, I encounter the following error:
"ContractDescription 'AppInitService' has zero operations; a contract must have at least one operation".
The domain service Url is this one:
http://givemeword.net/chat/Services/IM-Chat-UI-Web-DomainServices-AppInitService.svc
You can find the domain service class below:
namespace Chat.UI.Web.DomainServices
{
[EnableClientAccess()]
public class AppInitService : DomainService
{
private System.Security.Principal.IPrincipal _user;
private readonly Chat.UI.Web.Services.AppInitService _appInitService;
public AppInitService()
{
_appInitService = new Chat.UI.Web.Services.AppInitService();
}
public InitUserSettingsDTO InitUserSettings(Guid userId)
{
var initUserSettingsDTO = new InitUserSettingsDTO();
return initUserSettingsDTO;
}
}
}
As you can see, I am using a complex type as the return type of the only function of the domain service.
What I can not figure out is why on my testing Windows Server 2012 (not a development machine, just a virtual machine used for testing) or on my development machine everything runs without any problem, but on the hosting account it raise the error above.
Does anyone has any idea about this?
Thank you
Try adding the [Invoke] attribute to your InitUserSettings method:
[Invoke]
public InitUserSettingsDTO InitUserSettings(Guid userId)
{
var initUserSettingsDTO = new InitUserSettingsDTO();
return initUserSettingsDTO;
}
Make sure your web.config is set up as described here: http://msdn.microsoft.com/en-us/library/ff426912(v=vs.91).aspx
Being exasperated with this strange situation and the low support I received from the web hosting company, I have tried the same thing with another web provider. As I was thinking, it was working this time with no problems, so my assumption that the original provider had poor support for WCF RIA Services (or maybe other unidentified problem) was correct.

Registering Startup Class In Nancy Using AutoFac Bootstrapper

I've been reading through a lot of the Jabbr code to learn Nancy and trying to implement many of the same patterns in my own application. One of the things I can't seem to get working is the concept of an on application start class. The Jabbr code base has an App_Start folder with a Startup.cs file (here) in it with the following implementation.
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
...
SetupNancy(kernel, app);
...
}
}
private static void SetupNancy(IKernel kernel, IAppBuilder app)
{
var bootstrapper = new JabbRNinjectNancyBootstrapper(kernel);
app.UseNancy(bootstrapper);
}
When I tried to do something similar to that in my project the Startup.cs file was just ignored. I searched the Jabbr code base to see if it was used anywhere but I wasn't able to find anything and the only differences I could see is Jabbr uses Ninject while I wanted to use AutoFac
Is there a way to register a startup class in nancy?
Take a look at my project over on GitHub, you'll be interested in the Spike branch and may have to unload the ChainLink.Web project to run I can't remember.
I had some trouble finding a way to configure the ILifetimeScope even after reading the accepted answer here by TheCodeJunkie. Here's how you do the actual configuration:
In the bootstrapper class derived from the AutofacNancyBootstrapper, to actually configure the request container, you update the ILifetimeScope's component registry.
protected override void ConfigureRequestContainer(
ILifetimeScope container, NancyContext context)
{
var builder = new ContainerBuilder();
builder.RegisterType<MyDependency>();
builder.Update(container.ComponentRegistry);
}
The application container can be updated similarly in the ConfigureApplicationContainer override.
You should install the Nancy.Bootstrappers.Autofac nuget, inherit from the AutofacNancyBootstrapper type and override the appropriate method (depending on your lifetime scope requirements: application or request). For more info check the readme file https://github.com/nancyfx/nancy.bootstrappers.autofac
HTH
After following the advice from TheCodeJunkie you can use the Update method on the ILifetimeScope container parameter which gives you a ContainerBuilder through an Action:
protected override void ConfigureRequestContainer(ILifetimeScope container, NancyContext context)
{
container.Update(builder =>
{
builder.RegisterType<MyType>();
});
}

Log4Net in App object?

I am getting started with Logging in a WPF desktop app, using Log4Net as the logging component. Here is my question: In a simple desktop app, is there any reason not to instantiate my logger as a property ov the App class (App.xaml.cs), like this?
public partial class App : Application
{
private static readonly ILog p_Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public ILog Logger
{
get { return p_Logger; }
}
#endregion
}
}
That would allow me to invoke the logger
One reason springs to mind: since the App class's static constructor is the first bit of your code that will run, you will be instantiating the ILog instance before you've configured log4net. Therefore, you ILog instance won't be usable. Generally, you would instead do something like this:
public partial class App : Application
{
private static ILog log;
static App()
{
XmlConfigurator.Configure();
log = LogManager.GetLogger(typeof(App));
}
}
BTW, that MethodBase business really makes me cringe. Why not just use typeof(App)? You shouldn't be copy/pasting code without verifying it, anyway...and typeof(App) will work just fine with refactoring tools...
A couple of cases against using one global instance. By using one logger per class you get:
the benefit of logger hierarchies automatically following your class structure.
lesser coupling (your classes no longer have a dependency on the App class).
I did find a reason not to use a global logger in the App object. It works fine, but there is an advantage to getting a logger from within each class that will use it--It makes my log messages shorter and easier to write.
So I call GetLogger() in each class that will log, and I specify the name to be used for the logger. For example, in my OpenFile method, I can get a logger like this:
// Get logger
var logger = LogManager.GetLogger("OpenFile");
That relieves me of entering the class name in every error message I write. I still configure log4net in the App() constructor, since that only needs to be done once. That gives me a log message that looks like this:
2010-03-29 15:51:41,951 OpenFile [DEBUG]- Data file opened.
Kent's answer is still the accepted answer, but I figured I'd pass along what I had learned.

Resources