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" <[email protected]> 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 <[email protected]>
>> 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 十三郎 <[email protected]>
>>
>>> 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