Why i send error "WFLYEJB0054: Failed to marshal EJB parameters" with JAX-RS? - jax-rs

I have projects with two modules :EJB and JAX-RS
JAX-RS
Interface
package com.EJB;
#Remote
public interface TeamEJB {
public Response createTeam(String nameTeam, Set<Integer> idsHuman);
public Response test(String nameServer);
public Response changeMood(int id_team);
public Response getTeams();
}
Main controller
package com;
public class TeamServlet implements Serializable {
TeamEJB ejb= (TeamEJB) FactoriesKt.getFromEJBPool("ejb:/two/TeamEJBImpl!com.EJB.TeamEJB");
#GET
#Path("/test")
public Response test() {
String nameServer="OK 1 ";
return ejb.test(nameServer);
}
}
Modules EJB
interface
package com.EJB;
public interface TeamEJB {
public Response createTeam(String nameTeam, Set<Integer> idsHuman);
public Response test(String nameServer);
public Response changeMood(int id_team);
public Response getTeams();
}
Ejb-bean
package com.EJB;
#Stateless #Remote(TeamEJB.class)
public class TeamEJBImpl implements TeamEJB, Serializable {
private static final long serialVersionUID = 1L;
#Override
public Response test(String nameServer) {
return Response.ok().entity(nameServer).build();
}
}
But i get error
WFLYEJB0054: Failed to marshal EJB parameters
java.io.NotSerializableException: org.jboss.resteasy.specimpl.BuiltResponse

Related

Quarkus inject RequestInfo in bean

I'm able to inject RequesInfo instances in Jaxrs resources by using the #Context annotation.
What I'm trying to do is to inject the same interface but in a bean that is not a Jaxrs resource. This fails with a NPE when accessing the variable.
#RequestScoped
public class Service {
#Context
private ResourceInfo resourceInfo;
public Service() {
}
public ResourceInfo getResourceInfo() {
return resourceInfo;
}
}
#ApplicationScoped
#Path("/hello")
public class GreetingResource {
private final Service service;
#Inject
public GreetingResource(Service service) {
this.service = service;
}
#GET
#Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello RESTEasy";
}
#GET
#Path("service")
#Produces(MediaType.TEXT_PLAIN)
public String resourceInfoService() {
return service.getResourceInfo().getResourceClass().getName();
}
}
I have looked at Jaxrs spec but I did saw any clear evidence saying that this should be supported or not. I've used this technique in other spec implementations like Payara, but in Quarkus it fails.

how to inject depencies to constructor controller

I'm trying to configure an API which a controller use depency injection to inject an object to this controller
public class BaseAPIController
{
private readonly Repository _repository;
public BaseAPIController(Repository repository)
{
_repository = repository;
}
// some common functions and properties are declared here
}
public class AccountController : BaseAPIController
{
public AccountController(Repository repository) : base(repository)
{ }
}
but it throws an exception that tells "Some services are not able to be constructed..."
I tried a solution that use ILogger<Repository> instead of using Repository instance then this runs properly
public class AccountController : BaseAPIController
{
public AccountController(ILogger<Repository> repository) : base(repository)
{ }
}
the registion service in startup.cs code
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<IRepository, Repository>();
services.AddSingleton<WeatherForecastController, WeatherForecastController>();
}
and the declaration of Repository class
public interface IRepository
{
void DoSomething1();
void DoSomething2();
void DoSomething3();
}
public class Repository : IRepository
{
public readonly string _connectionString;
public Repository(string connectionString)
{
_connectionString = connectionString;
}
public void DoSomething1() {}
public void DoSomething2() {}
public void DoSomething3() {}
}
How can I archive the configuration above without using ILogger instance
Thanks
This is the registration you made:
services.AddScoped<IRepository, Repository>();
But this is AccountController's constructor:
AccountController(Repository repository)
Notice how AccountController is depending on the concrete type Repository; not on the IRepository interface. Because of this registration, Repository can only be resolved through its IRepository interface, but not directly (that's by MS.DI's design).
The solution, therefore, is to change AccountController's constructor to the following:
AccountController(IRepository repository)
The issue is that DI cannot create an instance of Repository because there is no parameterless constructor. Take a look at the docs for injecting settings rather than requiring a string in the constructor. Add your connection string to your appsettings.json file:
{
"AppSettings": {
"ConnectionString": "<connection_string>"
}
}
In ConfigureServices register your settings class:
public class AppSettings
{
public string ConnectionString;
}
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSection(AppSettings));
...
}
Then your Repository class constructor would look like this:
public Repository(IOptions<PositionOptions> options)
{
_connectionString = options.Value.ConnectionString;
}
You also need to inject the interface IRepository, not the concrete class into your controller.
public class BaseAPIController
{
private readonly IRepository _repository;
public BaseAPIController(IRepository repository)
{
_repository = repository;
}
// some common functions and properties are declared here
}

MEF Framework - How to pass interface to constructor method of a class in MEF

I am trying to implement MEF framework in my .Net core and .Net framework application. Here is my sample.
Project One class library:
[Export(typeof(IProductRepository))]
public class ProductRepository : IProductRepository
{
public ProductRepository(ApplicationDBContext context)
{
this.context = context;
}
}
Project Two class library:
[Export(typeof(IProductService))]
public class ProductService : IProductService
{
public ProductService(IProductRepository _ProductRepository)
{
}
}
So here both project depends on interface injection on constructor, and in another class library i am implementing the MEF like
[System.Composition.ImportMany]
public static IProductService ProductService{ get; set; }
[System.Composition.ImportMany]
public static IProductRepository ProductRepository{ get; set; }
var executableLocation = Assembly.GetEntryAssembly().Location;
var assemblies = Directory
.GetFiles(executableLocation , "*.dll", SearchOption.TopDirectoryOnly)
.Select(AssemblyLoadContext.Default.LoadFromAssemblyPath)
.ToList();
var configuration = new ContainerConfiguration().WithAssemblies(assemblies);
using (var container = configuration.CreateContainer())
{
ProductRepository= container.GetExport<IProductRepository>();
ProductService= container.GetExport<IProductService>();
}
Here I am getting error 'No export was found for the contract 'IProductRepository"IProductService"'
My question is,
how to pass an interface to constructor of class using MEF framework?
how to pass an object to constructor of class using MEF framework?
How to implement MEF when multiple projects are involved?
After searching I have found the answer it will goes as,
The repository code should be like below
[Export(typeof(IProductRepository))]
public class ProductRepository : IProductRepository
{
[ImportingConstructor]
public ProductRepository(ApplicationDBContext context)
{
this.context = context;
}
}
The service code should be like below
[Export(typeof(IProductService))]
public class ProductService : IProductService
{
[Import(typeof(IProductRepository ))]
private IProductRepository productRepository;
[ImportingConstructor]
public ProductService(IProductRepository _ProductRepository)
{
}
}
And using System.ComponentModel.Composition DLL implement the MEF container part as below
[Import(typeof(IProductService))]
public static IProductService ProductService { get; set; }
[Import(typeof(IProductRepository))]
public static IProductRepository ProductRepository { get; set; }
var catalog = new DirectoryCatalog(GlobalVariables.ApplicationAssemblyPath, "*.dll");
container = new CompositionContainer(catalog);
ProductRepository = container.GetExportedValue<IProductRepository>();
ProductService = container.GetExportedValue<IProductService>();
Hence from the ProductRepository, ProductService we will get the instance

Spring TestRestTemplate authentication

I am trying to build Spring Boot test to test rest API, so that I can get Principal from the request and use that to identify the user.
Server returns
{"timestamp":1502014507361,"status":403,"error":"Forbidden","message":"Access
Denied","path":"/hello"}
What am I missing here?
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class RestTemplateTest {
#Autowired
TestRestTemplate testRestTemplate;
#Test
public void testit() {
testRestTemplate.withBasicAuth("user", "password");
String responsePayload = testRestTemplate.getForObject("/hello", String.class);
}
#RestController
public class GreetingController {
#RequestMapping("/hello")
public String heipat(Principal principal) {
String string = "hello there";
return string;
}
#Configuration
#EnableWebSecurity
static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().anyRequest().hasRole("USER");
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
You need to be authenticated first. like requesting a /login API.
Also you need to make the login API accessible by everyone by doing this:
http.csrf().disable().authorizeRequests()
.antMatchers("/login").permitAll()
When you includes WebSecurityConfig you will have basic usernamerAndPassowrd authentication.

How can I inject multiple repositories in a NServicebus message handler?

I use the following:
public interface IRepository<T>
{
void Add(T entity);
}
public class Repository<T>
{
private readonly ISession session;
public Repository(ISession session)
{
this.session = session;
}
public void Add(T entity)
{
session.Save(entity);
}
}
public class SomeHandler : IHandleMessages<SomeMessage>
{
private readonly IRepository<EntityA> aRepository;
private readonly IRepository<EntityB> bRepository;
public SomeHandler(IRepository<EntityA> aRepository, IRepository<EntityB> bRepository)
{
this.aRepository = aRepository;
this.bRepository = bRepository;
}
public void Handle(SomeMessage message)
{
aRepository.Add(new A(message.Property);
bRepository.Add(new B(message.Property);
}
}
public class MessageEndPoint : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
public void Init()
{
ObjectFactory.Configure(config =>
{
config.For<ISession>()
.CacheBy(InstanceScope.ThreadLocal)
.TheDefault.Is.ConstructedBy(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());
config.ForRequestedType(typeof(IRepository<>))
.TheDefaultIsConcreteType(typeof(Repository<>));
}
}
My problem with the threadlocal storage is, is that the same session is used during the whole application thread. I discovered this when I saw the first level cache wasn't cleared. What I want is using a new session instance, before each call to IHandleMessages<>.Handle.
How can I do this with structuremap? Do I have to create a message module?
You're right in that the same session is used for all requests to the same thread. This is because NSB doesn't create new threads for each request. The workaround is to add a custom cache mode and have it cleared when message handling is complete.
1.Extend the thread storage lifecycle and hook it up a a message module
public class NServiceBusThreadLocalStorageLifestyle : ThreadLocalStorageLifecycle, IMessageModule
{
public void HandleBeginMessage(){}
public void HandleEndMessage()
{
EjectAll();
}
public void HandleError(){}
}
2.Configure your structuremap as follows:
For<<ISession>>
.LifecycleIs(new NServiceBusThreadLocalStorageLifestyle())
...
Hope this helps!