why #Inject cannot work but #EJB works in JavaEE 7? - ejb

I am going through JavaEE7-samples repo in github. I found that the author has mentioned the following in this code snippet:
// Cannot be injected using #Inject
#EJB Cart bean;
The author explicitly mentions that #Inject will not work. But I am wondering what is the reason behind it?
I have read the following posts on difference between #EJB and #Inject. but that did not help me here.
http://www.adam-bien.com/roller/abien/entry/inject_vs_ejb
What is the difference between #Inject and #EJB
Should I use #EJB or #Inject

Both will work if the bean has Local interface. However for #Inject to work you have to enable CDI (create beans.xml file in your WEB-INF folder).
If the bean has Remote interface you would need to have producer class to declare the resource with the following code:
public class RemoteProducer {
#Produces #EJB
HelloRemote helloBean;
}
For more details see section 3.5 in the JSR-299 CDI specification.
So for simplicity of usage I'd suggest to stick with #EJB for EJBs.

Related

StructureMap and classes that cannot accept constructor arguments

I have a ASP.NET web application (not MVC) which is actually a CMS application. I'm trying to set up StructureMap IoC framework and it's working well, but I've now hit a blocker in my understanding.
In my understanding, StructureMap enforces a pattern where all dependencies are registered in the core application assembly, so underlying assemblies do not themselves have a dependency on StructureMap.
So, say my application is My.App and it references another assembly My.Logic. My dependencies are all registered in a Container in My.App. This means that a class in My.Logic can take injected dependencies using a constructor like this:
public class Foo
{
private readonly IBar bar;
public Foo(IBar bar)
{
this.bar = bar;
}
}
But now I have a case where my class in My.Logic is a type which must be registered in the CMS, and this requires that it has an empty constructor.
So the problem is, if I can't inject using constructor parameters, and My.Logic doesn't have a dependency on My.App so I don't have access to the IoC container, is it possible to use StructureMap to handle this scenario?
If not, what alternative do I have other than create the class within the same assembly as the IoC container?
Use setter injection. See here
For<IBar>().Use<MyBar>();
Policies.FillAllPropertiesOfType<IBar>();

Customize Swagger Document Generation

I Have a spring boot application with following config.
#Configuration
#EnableWebMvc
#ComponentScan({ "com.xxx.mypackages" })
public class MyWebAppConfiguration extends WebMvcConfigurerAdapter {
}
In my project I have some web services and spring controllers. I want swagger to be enabled only in my web service classes. Currently, it generates documentation for both rest and controller classes. How can I customize that?
I'm using following dependency in gradle.
compile "com.mangofactory:swagger-springmvc:1.0.2"
If you look at the 1.0.2 documentation you'll find that SwaggerSpringMvcPlugin has a includePatterns method. This method takes a regular expression of the paths to include. For e.g. if you had an path prefix for the rest endpoints like this /rest/some-resource.... you could include a pattern, something like the snippet shown below
#Bean
public SwaggerSpringMvcPlugin customImplementation(){
return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
//... more config goes here
//regex to identify your rest services path
.includePatterns(".*rest.*");
}
Also it would be useful to know that we're going to be releasing 2.0 shortly with support for swagger spec 2.0. That might be something to consider as well.

Adding bindings in a test project with Ninject.MVC3

I'm having trouble figuring out what the best approach is these days for Ninject and ASP.NET MVC 3.
I have used Install-Package Ninject.MVC3 on my application and have my bootstrap class with the following methods:
public static void Start()
public static void Stop()
private static IKernel CreateKernel()
private static void RegisterServices(IKernel kernel)
It's all great and it loads my modules as expected. But historically what I have done is something like this:
MyApp.dll
Kernel.Bind<ISomething>().To<Something>();
Kernel.Bind<IBlah>().To<Blah>();
Kernel.Bind<IFoo>().To<Foo>();
MyApp.Tests.dll
Here I want to override ONLY ISomething's binding, so I used to just unbind the thing I needed to mock/whatever and rebind:
Kernel.Unbind<ISomething>();
Kernel.Bind<ISomethig>().To<TestSomething>();
But there isn't a method in the Nuget package that implies a thought through way to achieve this with the App_Start class from the original library. If I put another Ninject bootstrap class in my test app it only seems geared up to build a new kernel:
[assembly: WebActivator.PreApplicationStartMethod(typeof(TestNinjectBootstrapper), "Configure")]
I could store the kernel in the original bootstrapper statically and call from the tests project, but this feels wrong. Am I thinking too much and missing something? Or thinking too little :)
Argh. What is a good approach?
To reuse interface/class mapping registration in different project there is ability to create NInject modules. Modules just need to implement the INinjectModule interface, but most should extend the NinjectModule class for simplicity.
So you can place interface/class mapping inside module like in the following example:
public class WarriorModule : NinjectModule
{
public override void Load()
{
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf().InSingletonScope();
}
}
After you define such module you can instantiate Kernel with mapping defined in this module.
All that you need is to specify this module as argument during creating Kernel object:
IKernel kernel = new StandardKernel(new WarriorModule());
Note that you can create and instantiate kernel with multiple modules.
So, modules will help you to reuse default mapping configuration. Mapping configuration will be defined in one place which will simplify maintance especially if there are several projects which uses the same interface/class mapping configuration.
There are also some other features like 'Dynamic Module Loading' and etc. More information about modules can be found here.

#EJB not injected to JAX-RS

I have #LocalBeans and JAX-RS resources in different packages in a single ear.
And I also have a ServletFilter filtering before those resources.
I found that #EJB works for the ServletFilter but not for those resources.
#Stateless
#LocalBean
class MyBean { // in ejb jar
}
#WebFilter(urlPatterns = {"/*"})
class MyFilter implements Filter { // in the same war
#EJB MyBean myBean; // not null
}
#ApplicationPath("/")
class MyApplication extends Application { // in the same war
}
#Path("/my")
class MyResource { // in the same war
#EJB MyBean myBean; // null
}
No logs special, just an NPE in MyResource's method.
Can anybody help me?
UPDATE -----------------------------------------------
Making those resource classes as #Stateless do works.
But I just curious that those ejb-jar and web-war are assembled into a single ear.
And then the web-war is a web component, isn't it?
UPDATE2 ------------------------------------------------------
Oh, I'm sorry. There is also MyApplication that makes MyResource as a JAX-RS resource.
When I deploy the ear GF detect it as an 'Enterprise Application'.
UPDATE3 ---------------------------------------------------------------
Here comes my application.xml
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" version="6">
<display-name>sngp-v0-ear</display-name>
<module> <!-- EJBs are here -->
<ejb>sngp-v0-beans-1.0-alpha-1-SNAPSHOT.jar</ejb>
</module>
<module>
<web> <!-- JAX-RS are here -->
<web-uri>sngp-v0-mobile-resources-1.0-alpha-1-SNAPSHOT.war</web-uri>
<context-root>/sngp-v0-mobile-resources</context-root>
</web>
</module>
<library-directory>lib</library-directory>
</application>
MyResource class isn't either a web component or an enterprise bean, but you are trying to inject an EJB into it. EJB injection is guaranteed to work only when the client is either a web component or another enterprise bean.
Try making MyResource #Stateless.
Have a look at this Java EE 6 tutorial regarding EJB injection. If you are using NetBeans, I have also found useful using the built-in wizard for creating RESTFul web services. Check out this link in case.

Not able to parameterize an ejb function

I can write a ejb like this...
#Stateless
public class AnotherBean {
#PersistenceContext(unitName = "VoidJPA-ejbPU")
private EntityManager em;
public void newTest() {
System.out.println("Testing");
}
}
And call it using this from a servlet
#EJB
private AnotherBean nsb;
...
...
nsb.newTest();
But whenever i put a variable into newTest() i cannot access it
public void test(String i)
The servlet and EJB are both deployed but still
the server gives the error
WARNING: StandardWrapperValve[HelloEjb]: PWC1406: Servlet.service() for servlet
HelloEjb threw exception
java.lang.NoSuchMethodError: enew.AnotherBean.newTest(Ljava/lang/String;)V
at jpa.HelloEjb.processRequest(HelloEjb.java:44)
at jpa.HelloEjb.doGet(HelloEjb.java:85)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
.....
........
......
Any Help
Thanks
Pradyut
India
The Servlet clearly doesn't see the version of the Bean with the String parameter at runtime (you might have several versions on the classpath).
This could be a packaging issue, a deployment issue. You need to tell us more about the way you package and deploy your application.
Clean and rebuild your application then deploy again. Also check the dependencies. It seems the EJB contract is not visible to the servlet.
Ya i got it...
In netbeans i had to do the following...
Clean and Build the Ejb Project
Deploy the Ejb Project
Deploy the WebApplication(war) project (and make sure the ejb jar is in libraries which netbeans automatically does and needs no worry).

Resources