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