[JBoss Seam] - Re: Seam and Adobe Flex
by PatrickMadden
Should have been more clear. I'm using jdk 1.6u2 on the server side with JBoss AS 4.2.1.GA (from svn - its not really GA just yet but seams very stable). There are reasons I need to do this as we sometimes run into JRE 1.6 on client side with some Java WebStart applications and applets that are available to start from our seam based web app. There is new code in JDK 1.6 that was not there in 1.5 and it messes with normal operation of JBoss Web Services. Trust me, its true. With JBossWS 2.0.0.0GA, they add some extra jar files to the $Jboss.home/lib/endorsed directory to fix the problem.
My flex based components had difficulty speaking to the backend web services with the standard install of JBoss 4.2.0.GA and JBoss Web Services 1.2.1.GA and
Even if you have JDK 1.5 on the backend and for some reason use any remote standalone java application, webstart application or applet that may be using JRE 1.6 on the client (its not always easy to control btw what is on the client) you will run into issues with JBoss Web Services.
The issue at hand is Flex with Seam and how to talk to the backend, I have it running very nicely right now with EJB3 web services running in Seam.
But to answer your question, yes I don't believe you need to deal with JRE just to use flash/flex components and seam. Just be careful if you see errors such as xxx needs to overrride setProperty. Because if you do, its issues on the backend with java endorsed dirs.
Here is a small code example of my ActionScript 3 code that connects to an EJB3 Web Service running with Seam and JBoss.
| package com.clooster.as3.app.service
| {
| import flash.net.URLVariables;
|
| import flash.events.EventDispatcher;
| import flash.events.IEventDispatcher;
| import flash.net.URLRequest;
| import flash.net.URLRequestMethod;
| import flash.events.Event;
| import flash.net.URLLoader;
| import flash.utils.*;
| import flash.utils.describeType;
|
| import mx.controls.Alert;
| import mx.rpc.Fault;
| import mx.rpc.soap.WebService
| import mx.rpc.soap.LoadEvent;
| import mx.rpc.soap.SOAPDecoder;
| import mx.rpc.events.FaultEvent;
| import mx.rpc.events.ResultEvent;
|
| import com.clooster.as3.common.util.logging.Logger;
| import com.clooster.as3.common.events.WebServiceEvent;
| import mx.utils.ObjectUtil;
|
| public class CloosterFlashWebService extends EventDispatcher implements ICloosterFlashWebService
| {
| protected var sessionID:String;
| protected var logger:Logger = new Logger("CloosterFlashWebService");
|
| protected var webService:WebService = new WebService();
| protected var isAvailable:Boolean = false;
|
| public function CloosterFlashWebService(wsdlURL:String, asessionID:String, target:IEventDispatcher=null)
| {
| super(target);
| this.webService.addEventListener(LoadEvent.LOAD, onWSDLLoaded);
| this.webService.addEventListener(FaultEvent.FAULT, onWebServiceFault);
| this.webService.loadWSDL(wsdlURL);
| this.sessionID = asessionID;
| }
|
| protected function onWSDLLoaded(e:LoadEvent) : void
| {
| this.isAvailable = true;
|
| this.webService.navigateToParentGraph.addEventListener(
| ResultEvent.RESULT, onNavigateToParentGraph);
| this.webService.navigateToParentGraph.resultFormat = "e4x";
|
| this.webService.expandCluster.addEventListener(
| ResultEvent.RESULT, onExpandCluster);
| this.webService.expandCluster.resultFormat = "e4x";
|
| this.webService.globalLayout.addEventListener(
| ResultEvent.RESULT, onGlobalLayout);
| this.webService.globalLayout.resultFormat = "e4x";
| }
|
| private function onWebServiceFault(e:FaultEvent) : void
| {
| var fault:Fault = e.fault;
| var message:String = "An error occurred. The details are as follows\ncode: " + fault.faultCode;
| message += "\ndetail: " + fault.faultDetail;
| Alert.show("Web Service Error", message);
| }
|
| public function isAvailable() : Boolean
| {
| return this.isAvailable;
| }
|
| public function navigateToParentGraph():void
| {
| this.webService.navigateToParentGraph(this.sessionID);
| }
|
| protected function onNavigateToParentGraph(e:ResultEvent) : void
| {
| this.dispatchEvent(new WebServiceEvent(
| WebServiceEvent.NAVIGATETOPARENTGRAPH, e.result));
| }
|
| public function expandCluster(nodeID:uint):void
| {
| this.webService.expandCluster(this.sessionID, String(nodeID));
| }
|
| protected function onExpandCluster(e:ResultEvent) : void
| {
| this.dispatchEvent(new WebServiceEvent(
| WebServiceEvent.EXPANDCLUSTER, e.result));
| }
|
| public function globalLayout(layoutStyle:String):void
| {
| this.webService.globalLayout(this.sessionID, layoutStyle);
| }
|
| protected function onGlobalLayout(e:ResultEvent) : void
| {
| this.dispatchEvent(new WebServiceEvent(
| WebServiceEvent.GLOBALLAYOUT, e.result));
| }
| }
| }
|
My flex component is almost entirely implemented in Action Script and it draws diagrams that allow zooming, scrolling, and navigation up and down among a series of diagrams. Similar to a network diagram or a Visio chart.
The WebServiceEvent is a class I wrote that allows users to register for AS3 events against the web service class.
| package com.clooster.as3.common.events
| {
| import flash.events.Event;
|
| [Event(name="PERFORMSEARCHFROMNODE", type="com.clooster.as3.common.events.WebServiceEvent")]
| [Event(name="LOADSAVEDHEADLINESRESULT", type="com.clooster.as3.common.events.WebServiceEvent")]
| [Event(name="NAVIGATETOPARENTGRAPH", type="com.clooster.as3.common.events.WebServiceEvent")]
| [Event(name="EXPANDCLUSTER", type="com.clooster.as3.common.events.WebServiceEvent")]
| [Event(name="GLOBALLAYOUT", type="com.clooster.as3.common.events.WebServiceEvent")]
| [Event(name="PEFORMSEARCH", type="com.clooster.as3.common.events.WebServiceEvent")]
| [Event(name="GETSAVEDHEADLINESRESULTNAMES", type="com.clooster.as3.common.events.WebServiceEvent")]
| [Event(name="SAVEHEADLINES", type="com.clooster.as3.common.events.WebServiceEvent")]
| public class WebServiceEvent extends Event
| {
| public static const PERFORMSEARCHFROMNODE:String = "performSearchFromNode";
| public static const LOADSAVEDHEADLINESRESULT:String = "loadSavedHeadlineResult";
| public static const NAVIGATETOPARENTGRAPH:String = "navigateToParentGraph";
| public static const EXPANDCLUSTER:String = "expandCluster";
| public static const GLOBALLAYOUT:String = "globalLayout";
| public static const PEFORMSEARCH:String = "performSearch";
| public static const GETSAVEDHEADLINESRESULTNAMES:String = "SavedHeadlineResultNames";
| public static const SAVEHEADLINES:String = "saveHeadlines";
|
| protected var result:Object;
|
| /**
| * Constructor
| */
| public function WebServiceEvent(type:String, aresult:Object, bubbles:Boolean=false, cancelable:Boolean=false)
| {
| super(type, bubbles, cancelable);
| this.result = aresult;
| }
|
| /**
| * Returns the WebService for this event
| */
| public function getResult() : Object
| {
| return this.result;
| }
|
| /**
| * Creates a copy of the current instance
| * @return A copy of the current instance
| */
| public override function clone() : Event
| {
| return new WebServiceEvent(this.type, this.result, this.bubbles, this.cancelable);
| }
| }
| }
|
In one of my main flex application classes i create the web service and register for events as follows:
|
| public function getWebService() : CloosterFlashWebService
| {
| if (this.webService == null)
| {
| this.webService = new CloosterFlashWebService(
| this.getWebServiceURL(),
| this.getSessionID());
|
| registerWebServiceEventHandlers();
| }
|
| return this.webService;
| }
|
| protected function registerWebServiceEventHandlers() : void
| {
| this.getWebService().addEventListener(
| WebServiceEvent.NAVIGATETOPARENTGRAPH,
| onNewGraphXMLWebServiceHandler);
|
| this.getWebService().addEventListener(
| WebServiceEvent.EXPANDCLUSTER,
| onNewGraphXMLWebServiceHandler);
|
| this.getWebService().addEventListener(
| WebServiceEvent.GLOBALLAYOUT,
| onNewGraphXMLWebServiceHandler);
| }
|
| /**
| * Called when the web service returns an new graph xml result
| */
| protected function onNewGraphXMLWebServiceHandler(we:WebServiceEvent) : void
| {
| var xmlList:XMLList = XMLList(we.getResult());
| var graphXML:XML = xmlList[0];
|
The trick is that the result from the web service in flex in an XMLList from my testing you can just graph the first item in the list and its your SOAP xml envelope. For me, all my results are themselves XML and you can get the actual xml from the envelope as follows:
|
| var returnNodes:XMLList = graphXML.elements("return");
|
| if (returnNodes != null && returnNodes.length() == 1)
| {
| var returnNode:XML = returnNodes[0];
| var xmlString:String = returnNode.toString();
|
| // This is the actual xml returned from the method minus the envelope.
| this.graphXML = new XML(xmlString);
| }
|
|
Here is a small snippet of my backend service:
| /**
| *
| */
| package com.clooster.web.services.flash;
|
| import javax.ejb.Remote;
| import javax.ejb.Stateless;
| import javax.jws.WebMethod;
| import javax.jws.WebService;
| import javax.jws.soap.SOAPBinding;
|
| import org.jboss.annotation.ejb.RemoteBinding;
| import org.jboss.ws.annotation.WebContext;
|
| /**
| * @author PatrickMadden
| *
| */
|
| @WebService(name = "FlashServiceEndpointInterface", targetNamespace = "http://clooster.com/web/services/flash", serviceName = "FlashService")
| @SOAPBinding(style = SOAPBinding.Style.RPC)
| @Remote(EJB3RemoteFlashService.class)
| @RemoteBinding(jndiBinding = "/ejb3/EJB3FlashService")
| @Stateless
| @WebContext(transportGuarantee = "NONE", contextRoot = "/Clooster", urlPattern = "/common/services/FlashService")
| public class EJB3RemoteFlashServiceBean implements
| EJB3RemoteFlashService
| {
| /*
| * (non-Javadoc)
| *
| * @see com.clooster.web.services.EJB3RemoteFlashService#expandCluster(java.lang.String,
| * long)
| */
| @WebMethod
| public String expandCluster(String sessionID, long nodeID)
| {
|
So you should be able to something very similar to use seam, jboss, webservices and flex.
Just for completeness, I'll show you some of the xhtml with Rich Faces and JSF etc.
|
| <rich:tab label="Diagram">
| <head>
| <script type="text/javascript" src="./javascript/swfobject.js"></script>
| <script type="text/javascript" src="./javascript/cloosterflash.js"></script>
| </head>
| <div>
| <rich:toolBar>
| <table cellspacing="0" cellpadding="0" width="100%" border="0">
| <tr>
| <td class="menu_cell">
| <a href="javascript:flashNavigateToParentGraph()">
| <img title="Navigate Up" src="img/xjava/navigate_backward.gif" border="0"/>
| </a>
| </td>
| <td class="menu_cell">
| <a href="javascript:flashFitInCanvas()">
| <img title="Fit In Canvas" src="img/toolbar/fitInCanvas.gif" border="0"/>
| </a>
| </td>
| <td class="menu_cell">
| <a href="javascript:flashZoomIn()">
| <img title="Zoom In" src="img/toolbar/zoomIn.gif" border="0"/>
| </a>
| </td>
| <td class="menu_cell">
| <a href="javascript:flashZoomOut()">
| <img title="Zoom Out" src="img/toolbar/zoomOut.gif" border="0"/>
| </a>
| </td>
| <td class="menu_cell">
| <select id="zoom" onchange="flashZoomComboChanged();" name="zoom">
| <option value="200">200%</option>
| <option value="150">150%</option>
| <option value="100">100%</option>
| <option value="50">50%</option>
| <option value="25">25%</option>
| <option value="10">10%</option>
| </select>
| </td>
| <td class="menu_cell">
| <a href="javascript:flashToggleOverview()">
| <img title="Toggle Log Window" src="img/toolbar/view_overview.gif" border="0"/>
| </a>
| </td>
| <td class="menu_cell">
| <a href="javascript:flashToggleLogWindow()">
| <img title="Toggle Overview" src="img/toolbar/view_overview.gif" border="0"/>
| </a>
| </td>
| <td class="menu_cell">
| <a href="javascript:flashGlobalCLayout()">
| <img title="Circular Layout" src="img/toolbar/circular.gif" border="0"/>
| </a>
| </td>
| <td class="menu_cell">
| <a href="javascript:flashGlobalHLayout()">
| <img title="Hierarchical Layout" src="img/toolbar/hierarchical.gif" border="0"/>
| </a>
| </td>
| <td class="menu_cell">
| <a href="javascript:flashGlobalOLayout()">
| <img title="Orthogonal Layout" src="img/toolbar/othogonal.gif" border="0"/>
| </a>
| </td>
| <td class="menu_cell">
| <a href="javascript:flashGlobalSLayout()">
| <img title="Symmetric Layout" src="img/toolbar/symmetric.gif" border="0"/>
| </a>
| </td>
| </tr>
| </table>
| </rich:toolBar>
| </div>
| <div id="flashcontent" style="vertical-align: top;">
| <strong>You must update your Flash Player</strong>
| </div>
| <!-- Clooster.swf is the flex/flash movie and we name it 'GraphCanvas' for use in the cloosterflash.js -->
| <script type="text/javascript">
| var so = new FlashObject("./swf/Clooster.swf","GraphCanvas","100%","580px","9","#ffffff");
| so.addParam("scale", "noscale");
| so.addParam("align", "top");
| so.addParam("salign", "lt");
| so.addParam("wmode", "window");
|
| so.addVariable("appContextURL","#{search.externalApplicationRoot}");
| so.addVariable("graphURL","#{search.graphXMLDataURL}");
| so.addVariable("sessionID","#{search.sessionId}");
| so.addVariable("overviewControlVisible","false");
| so.addVariable("logWindowControlVisible", "false");
| so.write("flashcontent");
| </script>
| </rich:tab>
|
Hope this helps,
PVM
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4065228#4065228
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4065228
18Â years, 11Â months
[JBossCache] - Potential Deadlock - 1.4.1.SP3 and BoundedLinkedQueue
by mraccola
I am experiencing what appears to be a deadlock situation in JBoss Cache 1.4.1.SP3. After some period of time with the app up and running in JBoss AS 4.0.5 I am seeing one thread holding a couple of monitor locks in BoundedLinkedQueue and a multitude of threads waiting on the lock. The application grinds to a halt with users experiencing hanging HTTP responses.
In the latest scenario I have 28 HTTP threads,
26 are blocked (see Stack #1).
1 thread holds 2 locks (see Stack #2).
1 thread is still free (see Stack #3).
A Google search indicates that BoundedLinkedQueue has had issues with race conditions in the past, http://altair.cs.oswego.edu/pipermail/concurrency-interest/2004-September..., although the scenario seems slightly different.
Stack #1
"http-0.0.0.0-8080-12" daemon prio=1 tid=0x08c5bd58 nid=0x26e0 waiting for monitor entry [0x97cfc000..0x97cff030]
| at EDU.oswego.cs.dl.util.concurrent.BoundedLinkedQueue.put(Unknown Source)
| - waiting to lock <0xb4291690> (a java.lang.Object)
| at org.jboss.cache.eviction.Region.putNodeEvent(Region.java:141)
| at org.jboss.cache.interceptors.EvictionInterceptor.doEventUpdatesOnRegionManager(EvictionInterceptor.java:149)
| at org.jboss.cache.interceptors.EvictionInterceptor.updateNode(EvictionInterceptor.java:122)
| at org.jboss.cache.interceptors.EvictionInterceptor.invoke(EvictionInterceptor.java:97)
| at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
| at org.jboss.cache.interceptors.OptimisticCreateIfNotExistsInterceptor.invoke(OptimisticCreateIfNotExistsInterceptor.java:69)
| at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
| at org.jboss.cache.interceptors.OptimisticValidatorInterceptor.invoke(OptimisticValidatorInterceptor.java:87)
| at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
| at org.jboss.cache.interceptors.OptimisticLockingInterceptor.invoke(OptimisticLockingInterceptor.java:126)
| at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
| at org.jboss.cache.interceptors.TxInterceptor.handleNonTxMethod(TxInterceptor.java:365)
| at org.jboss.cache.interceptors.TxInterceptor.invoke(TxInterceptor.java:160)
| at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
| at org.jboss.cache.interceptors.CacheMgmtInterceptor.invoke(CacheMgmtInterceptor.java:138)
| at org.jboss.cache.TreeCache.invokeMethod(TreeCache.java:5863)
| at org.jboss.cache.TreeCache.get(TreeCache.java:3627)
| at org.jboss.cache.TreeCache.get(TreeCache.java:3608)
|
Stack #2
"http-0.0.0.0-8080-11" daemon prio=1 tid=0x087dab18 nid=0x2691 in Object.wait() [0x976f0000..0x976f3030]
| at java.lang.Object.wait(Native Method)
| at java.lang.Object.wait(Object.java:474)
| at EDU.oswego.cs.dl.util.concurrent.BoundedLinkedQueue.put(Unknown Source)
| - locked <0xb42914e8> (a EDU.oswego.cs.dl.util.concurrent.BoundedLinkedQueue)
| - locked <0xb4291690> (a java.lang.Object)
| at org.jboss.cache.eviction.Region.putNodeEvent(Region.java:141)
| at org.jboss.cache.interceptors.EvictionInterceptor.doEventUpdatesOnRegionManager(EvictionInterceptor.java:149)
| at org.jboss.cache.interceptors.EvictionInterceptor.updateNode(EvictionInterceptor.java:122)
| at org.jboss.cache.interceptors.EvictionInterceptor.invoke(EvictionInterceptor.java:97)
| at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
| at org.jboss.cache.interceptors.OptimisticCreateIfNotExistsInterceptor.invoke(OptimisticCreateIfNotExistsInterceptor.java:69)
| at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
| at org.jboss.cache.interceptors.OptimisticValidatorInterceptor.invoke(OptimisticValidatorInterceptor.java:87)
| at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
| at org.jboss.cache.interceptors.OptimisticLockingInterceptor.invoke(OptimisticLockingInterceptor.java:126)
| at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
| at org.jboss.cache.interceptors.TxInterceptor.handleNonTxMethod(TxInterceptor.java:365)
| at org.jboss.cache.interceptors.TxInterceptor.invoke(TxInterceptor.java:160)
| at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
| at org.jboss.cache.interceptors.CacheMgmtInterceptor.invoke(CacheMgmtInterceptor.java:138)
| at org.jboss.cache.TreeCache.invokeMethod(TreeCache.java:5863)
| at org.jboss.cache.TreeCache.get(TreeCache.java:3627)
| at org.jboss.cache.TreeCache.get(TreeCache.java:3608)
|
Stack #3
"http-0.0.0.0-8080-27" daemon prio=1 tid=0x09643720 nid=0x2fc0 in Object.wait() [0x978f7000..0x978f71b0]
| at java.lang.Object.wait(Native Method)
| - waiting on <0xc3c65dc0> (a org.apache.tomcat.util.net.MasterSlaveWorkerThread)
| at java.lang.Object.wait(Object.java:474)
| at org.apache.tomcat.util.net.MasterSlaveWorkerThread.await(MasterSlaveWorkerThread.java:81)
| - locked <0xc3c65dc0> (a org.apache.tomcat.util.net.MasterSlaveWorkerThread)
| at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:107)
| at java.lang.Thread.run(Thread.java:595)
|
TreeCache Configuration
<server>
| <classpath codebase="./lib" archives="jboss-cache.jar, jgroups.jar"/>
| <mbean code="org.jboss.cache.TreeCache" name="jboss.cache:service=TreeCache">
| <depends>jboss:service=Naming</depends>
| <depends>jboss:service=TransactionManager</depends>
| <attribute name="ClusterName">FCXp_hibernate</attribute>
| <attribute name="CacheMode">LOCAL</attribute>
| <attribute name="SyncReplTimeout">10000</attribute>
| <attribute name="LockAcquisitionTimeout">15000</attribute>
| <attribute name="FetchInMemoryState">false</attribute>
| <attribute name="NodeLockingScheme">OPTIMISTIC</attribute>
|
| <attribute name="EvictionPolicyClass"> org.jboss.cache.eviction.LRUPolicy </attribute>
| <attribute name="EvictionPolicyConfig">
| <config>
| <attribute name="wakeUpIntervalSeconds">10000</attribute>
| <!-- Cache wide default -->
| <region name="/_default_">
| <attribute name="maxNodes">200000</attribute>
| <attribute name="timeToIdleSeconds">10000</attribute>
| </region>
| </config>
| </attribute>
| </mbean>
| </server>
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4065227#4065227
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4065227
18Â years, 11Â months
[Security & JAAS/JBoss] - Automatic User Login Upon Registration in Application
by colddata
Hello,
I am trying to register a new user in the system and then automatically log him in so he can access secure myaccount.jsp page upon successful registration. The LDAP authentication goes well, no errors. However, when I try to redirect to the secure page, I am still getting login.html page. I want to avoid this extra step and have users be able to view secure resources upon successful registration in the system.
Am I missing something? Below is a snippet from the test JSP that handles authentication.
Thank you!
<%@page import="com.colddata.xxx.account.AccountManager"%>
<%@ page import="com.colddata.xxx.entity.User" %>
<%@ page import="java.util.Set" %>
<%@ page import="javax.security.auth.*" %>
<%@ page import="javax.security.auth.callback.*" %>
<%@ page import="javax.security.auth.login.LoginContext" %>
<%@ page import="javax.security.auth.login.LoginException" %>
<%@ page import="org.jboss.security.auth.callback.*" %>
<%@ page import="org.jboss.security.SimplePrincipal" %>
<%!
User user = null;
String nextPage = null;
%>
<%
nextPage = "/testapp/secure/account/myaccount.jsp";
// Create new user
user = new User(request);
AccountManager accountManager = new AccountManager();
accountManager.createNewUser(user);
// Programmatically log in new user
try {
SecurityAssociationHandler handler = new SecurityAssociationHandler();
SimplePrincipal principal = new SimplePrincipal(user.getUserID());
handler.setSecurityInfo(principal, user.getPassword().toCharArray());
LoginContext loginContext = new LoginContext("security_policy", (CallbackHandler)handler);
loginContext.login();
Subject subject = loginContext.getSubject();
Set principals = subject.getPrincipals();
principals.add(principal);
} catch(LoginException e) {
System.out.println("ERROR: Cannot login user " + user.getUserID() + ". " + e);
}
// Redirect to the My Account page
response.sendRedirect(nextPage);
out.flush();
%>
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4065224#4065224
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4065224
18Â years, 11Â months
[JBossCache] - Re: Overflow berfore OutOfMemory
by bstansberryï¼ jboss.com
Don't take this answer as meaning anything beyond what I literally say, (particularly re: any particular approach) as I'm posting quickly and am not going to be careful about wording. :)
Thinking about separating concerns and designing to make it easy to do that is a good thing IMHO.
E.g. eviction now involves
1) cache providing information about cache events that can be used to make decisions.
2) deciding if I need to evict
3) deciding what to evict
4) mechanics of evicting
5) a background thread spawned by the cache to handle 2-4.
To the extent the current eviction subsystem makes it difficult to use those features a la carte, it would be good in theory to make it easier. For the EJB3 SFSB caching case I could foresee only wanting JBC support for 1,2,3. There's already a slightly custom implementation of 4, implemented in a not very clean way. I'd also somewhat like to get rid of #5 and have the EJB container use its own thread.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4065217#4065217
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4065217
18Â years, 11Â months