My project is multi-module and is structured in this way:
common (JMX MBean interfaces).
agent (JMX MBean implementations and instrumentation code - here I register the MBeans)
plugin (here I "ask" for registered MBeans)
The problem is the plugin part uses a different classloader than the agent. Thus I receive
java.lang.ClassCastException: class com.github.lppedd.jmx.FeaturesMBean$Feature cannot be cast to class com.github.lppedd.jmx.FeaturesMBean$Feature
(com.github.lppedd.jmx.FeaturesMBean$Feature is in unnamed module of loader 'app';
com.github.lppedd.jmx.FeaturesMBean$Feature is in unnamed module of loader com.intellij.ide.plugins.cl.PluginClassLoader #35962a94)
The incriminated MBean is
public interface FeaturesMBean {
List<Feature> availableFeatures();
class Feature implements Serializable {
private static final long serialVersionUID = 1L;
public final String name;
public final String description;
public Feature(final String name, final String description) {
this.name = name;
this.description = description;
}
}
}
How should I deal with this issue?
Related
I created a project to test the dependency injection offered by Google Guice in my Jax-rs resources, using Resteasy.
My intentions are:
Use multiple #ApplicationPath for the versions of my API. In each class annotated with #ApplicationPath I load a set of classes for the specific version.
Each resource have a #Inject (from Google Guice) in his constructor to inject some services.
I created two classes annotated with #ApplicationPath: ApplicationV1RS and ApplicationV2RS. In both I added the same resources classes (UserResource and HelloResource), only for my test.
My Module is configured like this:
public class HelloModule implements Module
{
public void configure(final Binder binder)
{
binder.bind(IGreeterService.class).to(GreeterService.class);
binder.bind(IUserService.class).to(UserService.class);
}
}
When I call http://localhost:9095/v1/hello/world or http://localhost:9095/v2/hello/world, I receive the same error:
java.lang.RuntimeException: RESTEASY003190: Could not find constructor
for class: org.jboss.resteasy.examples.guice.hello.HelloResource
Well, as I expected, this not works. The Google Guice is not "smart" to instantiate the resource classes using the construtor for me.
But I can't find a way to work. To be really honest, I'm really confuse about how the Google Guice, Jetty and Resteasy play with each other in this scenario.
If I abandon the idea of use #ApplicationPath, my resources work with Google Guice configuring my HelloModule like this:
public class HelloModule implements Module
{
public void configure(final Binder binder)
{
binder.bind(HelloResource.class);
binder.bind(IGreeterService.class).to(GreeterService.class);
binder.bind(UserResource.class);
binder.bind(IUserService.class).to(UserService.class);
}
}
But in this case, I'm passing the control to register my resources (HelloResource and UserResource) to Guice. It's not flexible for me, I can't setup my multiple #ApplicationPath.
So, what I'm missing or not understanding?
I created a project with the problemetic code. Is very easy to setup and test: https://github.com/dherik/resteasy-guice-hello/tree/so-question/README.md
Thanks!
When you have getClasses method in your Application then it tries to create instance for all the registered resources using the default constructor which is missing in our Resources class. One way is to create a default constructor and Inject the dependencies through setter Injection.
And then instead of overriding getClasses in ApplicationV1RS and ApplicationV2RS you override getSingletons. Since Resources can be Singleton.
Below are the changes that I made to make it work the way you want.
ApplicationV1RS.java
#ApplicationPath("v1")
public class ApplicationV1RS extends Application {
private Set<Object> singletons = new HashSet<Object>();
public ApplicationV1RS(#Context ServletContext servletContext) {
}
#Override
public Set<Object> getSingletons() {
Injector injector = Guice.createInjector(new HelloModule());
HelloResource helloResource = injector.getInstance(HelloResource.class);
UserResource userResource = injector.getInstance(UserResource.class);
singletons.add(helloResource);
singletons.add(userResource);
return singletons;
}
}
ApplicationV2RS.java
#ApplicationPath("v2")
public class ApplicationV2RS extends Application {
private Set<Object> singletons = new HashSet<Object>();
public ApplicationV2RS(#Context ServletContext servletContext) {
}
#Override
public Set<Object> getSingletons() {
Injector injector = Guice.createInjector(new HelloModule());
HelloResource helloResource = injector.getInstance(HelloResource.class);
UserResource userResource = injector.getInstance(UserResource.class);
singletons.add(helloResource);
singletons.add(userResource);
return singletons;
}
}
HelloResource.java
#Path("hello")
public class HelloResource {
#Inject
private IGreeterService greeter;
public HelloResource() {
}
#GET
#Path("{name}")
public String hello(#PathParam("name") final String name) {
return greeter.greet(name);
}
}
UserResource.java
#Path("user")
public class UserResource {
#Inject
private IUserService userService;
public UserResource() {
}
#GET
#Path("{name}")
public String hello(#PathParam("name") final String name) {
return userService.getUser(name);
}
}
Add #Singleton to your Service Classes.
Hope it helps.
I have also pushed the code to forked repo. check it out
I have a problem with injecting EJB inside of a REST service (using jersey on glassfish 3.2 server) and I'm puzzled.
I have an EJB interface declared as:
import javax.ejb.Local;
#Local
public interface TestServiceLocal {
public String getText();
}
and the class bean that implements it:
import javax.ejb.Local;
import javax.ejb.Stateless;
/**
* Session Bean implementation class TestService
*/
#Stateless
#Local(TestServiceLocal.class)
public class TestService implements Serializable, TestServiceLocal {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public TestService() {
// TODO Auto-generated constructor stub
}
#Override
public String getText() {
return this.getClass().getName();
}
}
The REST service looks like:
#Path("/service")
#Stateless
public class TestRestService {
#EJB(beanName="TestService")
private TestServiceLocal testService;
public TestRestService () {
}
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/events")
public String getText() {
return testService.getText();
}
}
The problem is that when the REST service is called the bean cannot be created:
SEVERE: EJB5070: Exception creating stateless session bean : [TestRestService]
WARNING: EJB5184:A system exception occurred during an invocation on EJB TestRestService, method: public java.lang.String TestRestService.getText()
WARNING: javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:454)
at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2547)
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1899)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy839.getText(Unknown Source)
I had already took a look at the answers posted here but none of them seemed to work for me. Any help will be appreciated. Thank you!
PS: I forgot to mentioned (don't know if it's relevant). My project is created under eclipse Juno as Dynamic Web Project.
I am using Arquillian to inject the dependencies for my tests. It works OK if I inject the beans directly to my test class, but if the beans have dependencies of their own tht have to be injected, those dependencies do not get injected.
For example: the FacLptConfiguration bean gets imported correctly into my Test Class, but it does not get injected into the CfdFileCreator bean. I injected FacLptConfigurtion to the test class just to confirm that the injection works, but the user of this class is CfdFileCreator.
#RunWith(Arquillian.class)
public class CfdFileCreatorArquillianTest {
#Deployment
public static WebArchive createDepolyment() {
return ShrinkWrap.create(WebArchive.class)
.addClass(FacLptConfiguration.class)
.addClass(InterimFileCreator.class)
.addClass(CfdFileCreator.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsWebInfResource(new File("C:/aLearn/FacLpt/web/WEB-INF/env-entries.properties"));
}
public static String TEST_FOLDER = "C:/aLearn/FacLpt/src/test/testdata/pruebas/";
#Inject
private FacLptConfiguration facLptConfiguration;
#Inject
private CfdFileCreator cfdFileCreator;
#Test
public void createCfd() {
System.out.println("in createCFD");
cfdFileCreator.createCFDFile();
}
}
These injections are not working:
#Singleton
public class CfdFileCreator {
#Inject
private InterimFileCreator interimFileCreator;
#Inject
private FacLptConfiguration facLptConfiguration;
I think your problem is the location of the beans.xml. For a web archive it should be WEB-INF/beans.xml. Use:
addAsWebInfResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"))
See also https://community.jboss.org/thread/175404
This is the ManagedBean
#ManagedBean #ViewScoped public class DetailItem {
private static final long serialVersionUID = -7647929779133437125L;
#ManagedProperty(value = "#{itemServiceImpl}")
private ItemService servItem;
This is the Service
#Service("itemServiceImpl") #Transactional(value = "transactionManagerLocal") public class ItemServiceImpl implements ItemService {
private static final long serialVersionUID = 1L;
#Autowired
#Qualifier("itemDaoImpl")
private ItemDAO dao;
but when I try to access to the page that used 'DetailItem', I have the following exception:
java.io.NotSerializableException: org.springframework.dao.support.PersistenceExceptionTranslationInterceptor java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164) java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
To fix that I do the servItem transient and obtain it from the applicationContext. But I understand that it is not the correct solution and I dont find any other. Which is the proper way to do that?
I donĀ“t have the exception with sessionscoped or requestscoped.
Sounds like a similar problem like Serialization of ManagedProperty
Does ItemService implement Serializable and are all members of ItemServiceImpl serializable themselves?
I am trying to bind a repository to property using Ninject but always get null reference of binding object. I will explain the problem using code below.
public interface IServiceRepository
{
User GetUser(string email);
IQueryable<Statistic> GetStatisticForCurrentMonth(string ip);
void InsertStatistic(ConversionModel conversionModel);
class ServiceRepository : IServiceRepository
{
//Implementation of the Interface
}
I am would like to bind the repository above to class below while the class is created. Unfortunately Repository object is always null. Maybe I have misunderstood how Ninject is working? How to solve the problem?
public class Converter
{
[Inject]
public static IServiceRepository Repository { get; set; }
private static Converter _converter;
public static Converter Instance
{
get { return _Converter ?? (_Converter = new Converter ());
}
}
Ninject activator code
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IServiceRepository>().ToMethod(context => Converter.Repository);
}
Update
I have tried to rewrite code like this
public class Converter
{
private readonly IServiceRepository _repository;
public Converter(IServiceRepository repository)
{
_repository = repository;
}
//skip code
}
The test...
[TestMethod]
public void ConverterInstanceCreated()
{
using (IKernel kernel = new StandardKernel())
{
kernel.Bind<IServiceRepository>().To<ServiceRepository>();
Assert.IsNotNull(kernel.Get<Converter>());
}
}
gives exception
Test method PC.Tests.NinjectTest.ConverterInstanceCreated threw exception:
Ninject.ActivationException: Error activating IServiceRepository
No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IServiceRepository into parameter repository of constructor of type Converter
1) Request for Converter
I just lost, I am trying to understand how Ninject is working for about week without any success. In my case why this exception is thrown?
Also please someone post working example with one repository injection to singleton class.
Ninject does not inject statics. Change the coynverter to a non-static class and configure it as Singleton in ninject. Also use constructor injection and make the repo a private field.
Now you can inject the converter to the constructors where you need it.
Even though you are using Property injection and not Constructor injection I think it would still be
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IServiceRepository>().To<ServiceRepository>();
}
As ninject still just needs to know what concrete type to map to the Interface
I haven't tested this so apologies if it's wrong.