You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@deltaspike.apache.org by 十三郎 <mi...@163.com> on 2013/11/21 10:30:38 UTC
Re:Re: how to make DWR and CDI work together
hi,Jason Porter,Christian Kaltepoth:
Under your help,i write the CdiCreator that grabs the CDI managed instance.
i write two demos to test it in tomcat8rc5,jboss7.1.1.final, [@Inject] worked in a DWR way.
may be the code can help some pepole who use dwr and cdi.
==================================
/*
* Copyright 2005 Joe Walker
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.directwebremoting.create;
import java.util.Set;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Inject;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.directwebremoting.extend.AbstractCreator;
import org.directwebremoting.extend.Creator;
import org.directwebremoting.util.LocalUtil;
/**
* Get a CDI managedBean,
* and get the original instance from managedBean.
* @author Joe Walker [joe at getahead dot ltd dot uk]
*/
public class CdiCreator extends AbstractCreator implements Creator
{
/**
* this Creator make DWR work with CDI bean.
* @param cdiBeanName is the name of the cdi managedBean.
* the concept of cdi socpe unlike servlet scope,recommend not set scriptScpope.
*/
/*
* must add this dependency
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
* */
//Get cdi BeanManger
@Inject private BeanManager manager;
public void setClass(String classname)
{
try
{
clazz = LocalUtil.classForName(classname);
if (getJavascript() == null)
{
setJavascript(clazz.getSimpleName());
}
}
catch (ExceptionInInitializerError ex)
{
throw new IllegalArgumentException("Error loading class: " + classname, ex);
}
catch (ClassNotFoundException ex)
{
throw new IllegalArgumentException("Class not found: " + classname, ex);
}
}
/* (non-Javadoc)
* @see org.directwebremoting.Creator#getType()
*/
public Class<?> getType()
{
return clazz;
}
/* (non-Javadoc)
* @see org.directwebremoting.Creator#getInstance()
*/
public Object getInstance() throws InstantiationException
{
try
{
//Lookup BeanManger from JNDI
if(null==manager){
InitialContext initCtx;
initCtx = new InitialContext();
try{
//lookup JNDI BeanManager for jboss
manager = (BeanManager) initCtx.lookup("java:comp/BeanManager");;
} catch (NamingException e) {
System.out.println("cant get BeanManager from java:comp/ ");
}
if(null==manager){
//lookup JNDI BeanManager for tomcat
try{
manager = (BeanManager) initCtx.lookup("java:comp/env/BeanManager");
} catch (NamingException e) {
System.out.println("cant get BeanManager from java:comp/env/ ");
}
}
if(null==manager){
System.out.println("CDI not support on this environment.");
return null;
}
}
//Get a defalut managedBeanName if cdiBeanName is blank
if(cdiBeanName==null || cdiBeanName.equals("")){
String className=clazz.getSimpleName();
cdiBeanName=className.substring(0,1).toLowerCase()+className.substring(1);
//may be cdiBeanName not equal with real cdi beanName
}
//Get cdi managedBeanName by beanName
Set<Bean<?>> cdiBeans=manager.getBeans(cdiBeanName);
if(!cdiBeans.isEmpty()){
Bean<?> cdiBean = cdiBeans.iterator().next();
CreationalContext<?> crtCtx = manager.createCreationalContext(cdiBean);
Object instance=manager.getReference(cdiBean, clazz, crtCtx);
return instance;
}else{
System.out.println("fail to get CDI bean with cdiBeanName [ "+cdiBeanName+" ]");
return null;
}
}
catch (Exception ex)
{
throw new InstantiationException("Illegal Access to default constructor on " + clazz.getName());
}
}
/**
* Sets the class name to create.
* @param className The name of the class to create
*/
public void setClassName(String className)
{
setClass(className);
}
/**
* Gets the name of the class to create.
* @return The name of the class to create
*/
public String getClassName()
{
return getType().getName();
}
/**
* Set The cdi managed BeanName
*/
public void setCdiBeanName(String name){
this.cdiBeanName=name;
}
/**
* Get The cdi managed BeanName
*/
public String getCdiBeanName(){
return this.cdiBeanName;
}
/**
* The cdi managed BeanName
*/
private String cdiBeanName=null;
/**
* The type of the class that we are creating
*/
private Class<?> clazz;
}
======================
after that,add a dwr remote annotation like this:
@RemoteProxy(creator=CdiCreator.class,name="JsForDwr",creatorParams ={@Param(name = "cdiBeanName", value = "mybean")})
or a defaut way:
@RemoteProxy(creator=CdiCreator.class)
====================
thus,coder can use the javascript
[<script type='text/javascript' src='dwr/interface/JsForDwr.js'></script>] to call cdi bean.
dwr currently building with Java 5,they said the cdi support will be added when move to Java 6.
At 2013-11-11 05:01:51,"Jason Porter" <li...@gmail.com> wrote:
>I've never used DWR either, but this would be my assumption as well.
>
>Sent from my iPhone
>
>> On Nov 10, 2013, at 12:14, Christian Kaltepoth <ch...@kaltepoth.de> wrote:
>>
>> Hey,
>>
>> I think that @Inject doesn't work because DWR creates its own instance of
>> your class and doesn't use the CDI managed one. You have basically two
>> options here.
>>
>> Your first option is to tell DWR to use the CDI managed instance of you
>> class instead of creating a new one. As I'm not familiar with DWR I cannot
>> tell you how to do this. But there seems to be a Spring support module for
>> DWR, so it should be possible to do something similar for CDI.
>>
>> Your second option is to use BeanProvider.injectFields(this) somewhere in
>> your class. This way DeltaSpike will inject all dependencies into your
>> object even if it has been created by DWR.
>>
>> I hope this helps
>>
>> Christian
>>
>>
>>
>>
>> 2013/11/10 十三郎 <mi...@163.com>
>>
>>> hi,erveryone.
>>>
>>> in a DWR RemoteMethod,dwr cant get injected bean automatical.
>>> like this:
>>> --------------
>>> import javax.inject.Inject;
>>> import javax.inject.Named;
>>> import org.apache.deltaspike.core.api.provider.BeanProvider;
>>> import org.directwebremoting.annotations.RemoteMethod;
>>> import org.directwebremoting.annotations.RemoteProxy;
>>> @Named("Test")
>>> @RemoteProxy //for dwr
>>> public class Test
>>> {
>>> @Inject private User user;
>>> @RemoteMethod //for dwr
>>> public String test(){
>>> //i find dwr cant get @Inject bean
>>> System.out.println("user is null ? "+(user == null));
>>>
>>> //fortunately , i can get it in a manual way. but i dont wanna
>>> this way
>>> user=BeanProvider.getContextualReference(User.class,false);
>>> System.out.println("user name is: "+user.getUsername());
>>> return user.getUsername();
>>> }
>>> }
>>>
>>> import java.io.Serializable;
>>> import javax.enterprise.context.SessionScoped;
>>> import javax.inject.Named;
>>> @SessionScoped
>>> @Named
>>> public class User implements Serializable{
>>> private static final long serialVersionUID = -559381017984772756L;
>>> private String username="wuhenge";
>>> public String getUsername(){
>>> return this.username;
>>> }
>>> public void setUsername(String s){
>>> this.username=s;
>>> }
>>> }
>>> --------
>>> after run this demo,i find dwr can get inject bean in a manual way.but i
>>> dont wanna this way
>>>
>>> i try to add deltaspike servlet module,but that didnt work.
>>>
>>> the edition of dwr is latest on
>>> http://ci.directwebremoting.org/bamboo/browse/DWRTRUNK-ALL-521/artifact.
>>>
>>> thanks erveryone!!!!
>>
>>
>> --
>> Christian Kaltepoth
>> Blog: http://blog.kaltepoth.de/
>> Twitter: http://twitter.com/chkal
>> GitHub: https://github.com/chkal
Re:Re: how to make DWR and CDI work together
Posted by Jason Porter <li...@gmail.com>.
Awesome! That's a great contribution for dwr!
—
Sent from Mailbox for iPhone
On Thu, Nov 21, 2013 at 2:31 AM, 十三郎 <mi...@163.com> wrote:
> hi,Jason Porter,Christian Kaltepoth:
> Under your help,i write the CdiCreator that grabs the CDI managed instance.
> i write two demos to test it in tomcat8rc5,jboss7.1.1.final, [@Inject] worked in a DWR way.
> may be the code can help some pepole who use dwr and cdi.
> ==================================
> /*
> * Copyright 2005 Joe Walker
> *
> * Licensed under the Apache License, Version 2.0 (the "License");
> * you may not use this file except in compliance with the License.
> * You may obtain a copy of the License at
> *
> * http://www.apache.org/licenses/LICENSE-2.0
> *
> * Unless required by applicable law or agreed to in writing, software
> * distributed under the License is distributed on an "AS IS" BASIS,
> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> * See the License for the specific language governing permissions and
> * limitations under the License.
> */
> package org.directwebremoting.create;
> import java.util.Set;
> import javax.enterprise.context.spi.CreationalContext;
> import javax.enterprise.inject.spi.Bean;
> import javax.enterprise.inject.spi.BeanManager;
> import javax.inject.Inject;
> import javax.naming.InitialContext;
> import javax.naming.NamingException;
> import org.directwebremoting.extend.AbstractCreator;
> import org.directwebremoting.extend.Creator;
> import org.directwebremoting.util.LocalUtil;
> /**
> * Get a CDI managedBean,
> * and get the original instance from managedBean.
> * @author Joe Walker [joe at getahead dot ltd dot uk]
> */
> public class CdiCreator extends AbstractCreator implements Creator
> {
> /**
> * this Creator make DWR work with CDI bean.
> * @param cdiBeanName is the name of the cdi managedBean.
> * the concept of cdi socpe unlike servlet scope,recommend not set scriptScpope.
> */
>
> /*
> * must add this dependency
> <dependency>
> <groupId>javax.servlet</groupId>
> <artifactId>servlet-api</artifactId>
> <version>2.5</version>
> </dependency>
> * */
> //Get cdi BeanManger
> @Inject private BeanManager manager;
>
> public void setClass(String classname)
> {
> try
> {
> clazz = LocalUtil.classForName(classname);
> if (getJavascript() == null)
> {
> setJavascript(clazz.getSimpleName());
> }
> }
> catch (ExceptionInInitializerError ex)
> {
> throw new IllegalArgumentException("Error loading class: " + classname, ex);
> }
> catch (ClassNotFoundException ex)
> {
> throw new IllegalArgumentException("Class not found: " + classname, ex);
> }
> }
> /* (non-Javadoc)
> * @see org.directwebremoting.Creator#getType()
> */
> public Class<?> getType()
> {
> return clazz;
> }
> /* (non-Javadoc)
> * @see org.directwebremoting.Creator#getInstance()
> */
> public Object getInstance() throws InstantiationException
> {
> try
> {
> //Lookup BeanManger from JNDI
> if(null==manager){
> InitialContext initCtx;
> initCtx = new InitialContext();
> try{
> //lookup JNDI BeanManager for jboss
> manager = (BeanManager) initCtx.lookup("java:comp/BeanManager");;
> } catch (NamingException e) {
> System.out.println("cant get BeanManager from java:comp/ ");
> }
> if(null==manager){
> //lookup JNDI BeanManager for tomcat
> try{
> manager = (BeanManager) initCtx.lookup("java:comp/env/BeanManager");
> } catch (NamingException e) {
> System.out.println("cant get BeanManager from java:comp/env/ ");
> }
> }
> if(null==manager){
> System.out.println("CDI not support on this environment.");
> return null;
> }
>
> }
>
> //Get a defalut managedBeanName if cdiBeanName is blank
> if(cdiBeanName==null || cdiBeanName.equals("")){
> String className=clazz.getSimpleName();
> cdiBeanName=className.substring(0,1).toLowerCase()+className.substring(1);
> //may be cdiBeanName not equal with real cdi beanName
> }
> //Get cdi managedBeanName by beanName
> Set<Bean<?>> cdiBeans=manager.getBeans(cdiBeanName);
> if(!cdiBeans.isEmpty()){
> Bean<?> cdiBean = cdiBeans.iterator().next();
> CreationalContext<?> crtCtx = manager.createCreationalContext(cdiBean);
> Object instance=manager.getReference(cdiBean, clazz, crtCtx);
> return instance;
> }else{
> System.out.println("fail to get CDI bean with cdiBeanName [ "+cdiBeanName+" ]");
> return null;
> }
> }
> catch (Exception ex)
> {
> throw new InstantiationException("Illegal Access to default constructor on " + clazz.getName());
> }
> }
> /**
> * Sets the class name to create.
> * @param className The name of the class to create
> */
> public void setClassName(String className)
> {
> setClass(className);
> }
> /**
> * Gets the name of the class to create.
> * @return The name of the class to create
> */
> public String getClassName()
> {
> return getType().getName();
> }
> /**
> * Set The cdi managed BeanName
> */
> public void setCdiBeanName(String name){
> this.cdiBeanName=name;
> }
>
> /**
> * Get The cdi managed BeanName
> */
> public String getCdiBeanName(){
> return this.cdiBeanName;
> }
>
> /**
> * The cdi managed BeanName
> */
> private String cdiBeanName=null;
>
> /**
> * The type of the class that we are creating
> */
> private Class<?> clazz;
>
> }
> ======================
> after that,add a dwr remote annotation like this:
> @RemoteProxy(creator=CdiCreator.class,name="JsForDwr",creatorParams ={@Param(name = "cdiBeanName", value = "mybean")})
> or a defaut way:
> @RemoteProxy(creator=CdiCreator.class)
> ====================
> thus,coder can use the javascript
> [<script type='text/javascript' src='dwr/interface/JsForDwr.js'></script>] to call cdi bean.
> dwr currently building with Java 5,they said the cdi support will be added when move to Java 6.
> At 2013-11-11 05:01:51,"Jason Porter" <li...@gmail.com> wrote:
>>I've never used DWR either, but this would be my assumption as well.
>>
>>Sent from my iPhone
>>
>>> On Nov 10, 2013, at 12:14, Christian Kaltepoth <ch...@kaltepoth.de> wrote:
>>>
>>> Hey,
>>>
>>> I think that @Inject doesn't work because DWR creates its own instance of
>>> your class and doesn't use the CDI managed one. You have basically two
>>> options here.
>>>
>>> Your first option is to tell DWR to use the CDI managed instance of you
>>> class instead of creating a new one. As I'm not familiar with DWR I cannot
>>> tell you how to do this. But there seems to be a Spring support module for
>>> DWR, so it should be possible to do something similar for CDI.
>>>
>>> Your second option is to use BeanProvider.injectFields(this) somewhere in
>>> your class. This way DeltaSpike will inject all dependencies into your
>>> object even if it has been created by DWR.
>>>
>>> I hope this helps
>>>
>>> Christian
>>>
>>>
>>>
>>>
>>> 2013/11/10 十三郎 <mi...@163.com>
>>>
>>>> hi,erveryone.
>>>>
>>>> in a DWR RemoteMethod,dwr cant get injected bean automatical.
>>>> like this:
>>>> --------------
>>>> import javax.inject.Inject;
>>>> import javax.inject.Named;
>>>> import org.apache.deltaspike.core.api.provider.BeanProvider;
>>>> import org.directwebremoting.annotations.RemoteMethod;
>>>> import org.directwebremoting.annotations.RemoteProxy;
>>>> @Named("Test")
>>>> @RemoteProxy //for dwr
>>>> public class Test
>>>> {
>>>> @Inject private User user;
>>>> @RemoteMethod //for dwr
>>>> public String test(){
>>>> //i find dwr cant get @Inject bean
>>>> System.out.println("user is null ? "+(user == null));
>>>>
>>>> //fortunately , i can get it in a manual way. but i dont wanna
>>>> this way
>>>> user=BeanProvider.getContextualReference(User.class,false);
>>>> System.out.println("user name is: "+user.getUsername());
>>>> return user.getUsername();
>>>> }
>>>> }
>>>>
>>>> import java.io.Serializable;
>>>> import javax.enterprise.context.SessionScoped;
>>>> import javax.inject.Named;
>>>> @SessionScoped
>>>> @Named
>>>> public class User implements Serializable{
>>>> private static final long serialVersionUID = -559381017984772756L;
>>>> private String username="wuhenge";
>>>> public String getUsername(){
>>>> return this.username;
>>>> }
>>>> public void setUsername(String s){
>>>> this.username=s;
>>>> }
>>>> }
>>>> --------
>>>> after run this demo,i find dwr can get inject bean in a manual way.but i
>>>> dont wanna this way
>>>>
>>>> i try to add deltaspike servlet module,but that didnt work.
>>>>
>>>> the edition of dwr is latest on
>>>> http://ci.directwebremoting.org/bamboo/browse/DWRTRUNK-ALL-521/artifact.
>>>>
>>>> thanks erveryone!!!!
>>>
>>>
>>> --
>>> Christian Kaltepoth
>>> Blog: http://blog.kaltepoth.de/
>>> Twitter: http://twitter.com/chkal
>>> GitHub: https://github.com/chkal