Re: [jboss-dev-forums] [JBoss AS 7 Development] - Remote EJB distributed transactions and recovery
by Radek Rodak
Radek Rodak [https://community.jboss.org/people/rodakr] commented on the document
"Remote EJB distributed transactions and recovery"
To view all comments on this document, visit: https://community.jboss.org/docs/DOC-48398#comment-11623
--------------------------------------------------
bad idea to reimplement XA Transaction handling just for two servers and one specific EJB client API, when you have a separate project specialised for complex problem like XA two face commit.
Typically you don't have just two servers for XA recovery but, often XA Transaction is spawn over TXT Datasource(s) which interact also with TX Manager from DB. Or if you have JMS Ressources like Queue or Topic with TXT Connection Factory.
What if Stand Alone Client is using EJB API to communicate to a Server A EJB , but this EJB calls Server B EJB over let say iiop...?
What if TXT start was issued outside of Server or if Serve A and Server B are back, but the DB is still down.. ?
--------------------------------------------------
11 years, 10 months
Re: [jboss-dev-forums] [JBoss AS 7 Development] - Single Installation Patching
by Brian Stansberry
Brian Stansberry [https://community.jboss.org/people/brian.stansberry] commented on the document
"Single Installation Patching"
To view all comments on this document, visit: https://community.jboss.org/docs/DOC-47500#comment-11622
--------------------------------------------------
Sorry David, for not replying long ago. I'm fine with a disabling mechanism, particularly if it's ok to undo the change on a patch rollback. My inclination is to add a UI element such that we warn the user of the presence of this kind of change and require them to pass a flag allowing it. It's less critical that we do that if we allow re-enabling on rollback. But it may still be nice as it will help avoid suprises, e.g. if the disabled jar was on a classpath.
As for RPM, +1. I want the approach we follow here to be generally consistent with RPM patching, so a user who is familiar with RPM will have a general sense of how what we're doing will behave, and so a user who is accustomed to this tool who then moves to RPM is reasonably comfortable. As for actually using this tool on an installation that was provisioned via RPM -- that was not part of the original requirements for the tool. I would want to hear a clear example of how the two could mix and what the benefits would be before I'd go to my management to look into getting resources to make that happen.
--------------------------------------------------
11 years, 10 months
[JBoss AS 7 Development] - Remote EJB distributed transactions and recovery
by jaikiran pai
jaikiran pai [https://community.jboss.org/people/jaikiran] modified the document:
"Remote EJB distributed transactions and recovery"
To view the document, visit: https://community.jboss.org/docs/DOC-48398
--------------------------------------------------------------
h1. Overview
Unlike previous JBoss AS versions, remote transaction propagation between 2 server instances for EJB invocations does *not* require JTS. EJB client API which was introduced in AS7 uses its own protocol for remote transaction propagation between the client and the server for EJB invocations.
h1. Typical scenario
Let's consider an EJB A hosted on Server 1 and EJB B hosted on Server 2. EJBs are transactional by default. There are ways to disable transactions on EJBs or certain business methods of EJBs. But we won't be going into that part, in this article because our intention is to focus on the transaction propagation and recovery for EJBs, which obviously will require transactional EJBs.
When a client, for example a standalone Java application, invokes on EJB A (on Server 1) a transaction is created. Later, during that invocation request, if EJB A in turn invokes on EJB B (on Server 2), the transaction propagation is carried out between the servers hosting those 2 EJBs. Previous versions of JBoss AS require JTS for the transaction propagation to happen. However in AS7 we have a JBoss specific protocol implemented in EJB client API which does the necessary propagation. The EJB client API interacts with the transaction manager on Server 1 and Server 2 to carry out the necessary transaction propagation and management. Furthermore on the server side of the interaction (i.e. of Server 2 in this case), the AS7 EJB integration layer (heavily) uses JBoss Transaction project (Narayana) APIs to import the remote transaction and further manage it.
h1. Crash and transaction recovery
JBoss Transactions (Narayana) project provides the necessary API infrastructure for libraries like the EJB client API project to integrate for transaction recovery in case of client/server crash scenarios. The design of that API is explained in the JBoss Transactions project manual here http://docs.jboss.org/jbosstm/4.17.3.Final/guides/failure_recovery_guide/ http://docs.jboss.org/jbosstm/4.17.3.Final/guides/failure_recovery_guide/.
>From a EJB client API perspective, a org.jboss.tm.XAResourceRecovery implementation needs to be registered against the transaction subsystem's recovery manager service. This implementation of XAResourceRecovery is responsible for returning instances of XAResource(s) when the getXAResources() method is invoked by the recovery manager on that implementation. The returned XAResource(s) will then be used by the recovery manager to invoke the:
/**
* Obtains a list of prepared transaction branches from a resource manager. The transaction manager calls this method
* during recovery to obtain the list of transaction branches that are currently in prepared or heuristically completed states.
*/
javax.transaction.xa.Xid[] recover(int i) throws javax.transaction.xa.XAException;
As is evident from the name of the method, the implementation is responsible for returning the Xid(s) which need to be recovered.
h1. XAResourceRecovery implementation for EJB client API
As explained in the JBoss Transactions document, the recovery process involves a background thread which runs at periodic intervals to check for transactions that should be recovered. From a EJB client API perspective, it has to know the target server against which it is issuing a recover request and also the node identifier of the node/server on which the (previously run) transaction(s) originated.
h2. Node identifier of the transaction origin
This is also known as the "parent node name". This is the node on which the transaction, which was propagated, originated. The transaction subsystem integration in AS7 exposes this node identifier via the CoreEnvironmentService:
package org.jboss.as.txn.service;
public class CoreEnvironmentService implements Service<CoreEnvironmentBean> {
...
}
package com.arjuna.ats.arjuna.common;
public class CoreEnvironmentBean implements CoreEnvironmentBeanMBean {
....
public String getNodeIdentifier() {
return nodeIdentifier;
}
So it's straightforward for the EJB client integration in AS7 to know what the node identifier of itself.
h2. Target server(s)/EJBReceiver(s) against which the recover request has to be issued
The EJBClientContext can potentially contain numerous EJBReceiver(s), each of which correspond to a different node. Furthermore, the EJBReceiver(s) within a EJBClientContext can be dynamic - which means at it may not always contain the same set of EJBReceiver(s). Certain receivers may be added or removed as and when such a need arises. As such, there's no fixed set of EJBReceiver(s) which the EJBClientContext can known before hand to issue the recovery request against. So how does the EJB client API know which EJBReceiver(s) should it issue the recovery request when the recovery manager background process asks it for the Xid[] that need to be recovered.
The answer to that question is that whenever a EJBReceiver is registered in a EJBClientContext, it will make that EJBReceiver eligible for issuing a recovery request against. This is a very important thing to remember since if a server/EJBReceiver was being used during EJB invocations and either the server or client crashed, then the recovery against the server/EJBReceiver will not be triggered unless that EJBReceiver gets registered within a EJBClientContext. This however isn't a restriction since a recovery process between 2 servers only makes sense when they are communicating with each other and from a EJB client API perspective, the communication can only happen when the EJBReceiver is registered in a EJBClientContext.
h1. Implementation note
The EJB client project will *not* have any dependency on the JBoss Transactions (Narayana) project. All of the details being discussed in this article will be implemented in a way such that the AS7 EJB integration part can provide the necessary plugins to the EJB client library for allowing the recovery process to be carried out.
--------------------------------------------------------------
Comment by going to Community
[https://community.jboss.org/docs/DOC-48398]
Create a new document in JBoss AS 7 Development at Community
[https://community.jboss.org/choose-container!input.jspa?contentType=102&c...]
11 years, 10 months
[JBoss AS 7 Development] - Remote EJB distributed transactions and recovery
by jaikiran pai
jaikiran pai [https://community.jboss.org/people/jaikiran] modified the document:
"Remote EJB distributed transactions and recovery"
To view the document, visit: https://community.jboss.org/docs/DOC-48398
--------------------------------------------------------------
h1. Overview
Unlike previous JBoss AS versions, remote transaction propagation between 2 server instances for EJB invocations does *not* require JTS. EJB client API which was introduced in AS7 uses its own protocol for remote transaction propagation between the client and the server for EJB invocations.
h1. Typical scenario
Let's consider an EJB A hosted on Server 1 and EJB B hosted on Server 2. EJBs are transactional by default. There are ways to disable transactions on EJBs or certain business methods of EJBs. But we won't be going into that part, in this article because our intention is to focus on the transaction propagation and recovery for EJBs, which obviously will require transactional EJBs.
When a client, for example a standalone Java application, invokes on EJB A (on Server 1) a transaction is created. Later, during that invocation request, if EJB A in turn invokes on EJB B (on Server 2), the transaction propagation is carried out between the servers hosting those 2 EJBs. Previous versions of JBoss AS require JTS for the transaction propagation to happen. However in AS7 we have a JBoss specific protocol implemented in EJB client API which does the necessary propagation. The EJB client API interacts with the transaction manager on Server 1 and Server 2 to carry out the necessary transaction propagation and management. Furthermore on the server side of the interaction (i.e. of Server 2 in this case), the AS7 EJB integration layer (heavily) uses JBoss Transaction project (Narayana) APIs to import the remote transaction and further manage it.
h1. Crash and transaction recovery
JBoss Transactions (Narayana) project provides the necessary API infrastructure for libraries like the EJB client API project to integrate for transaction recovery in case of client/server crash scenarios. The design of that API is explained in the JBoss Transactions project manual here http://docs.jboss.org/jbosstm/4.17.3.Final/guides/failure_recovery_guide/ http://docs.jboss.org/jbosstm/4.17.3.Final/guides/failure_recovery_guide/.
>From a EJB client API perspective, a org.jboss.tm.XAResourceRecovery implementation needs to be registered against the transaction subsystem's recovery manager service. This implementation of XAResourceRecovery is responsible for returning instances of XAResource(s) when the getXAResources() method is invoked by the recovery manager on that implementation. The returned XAResource(s) will then be used by the recovery manager to invoke the:
/**
* Obtains a list of prepared transaction branches from a resource manager. The transaction manager calls this method
* during recovery to obtain the list of transaction branches that are currently in prepared or heuristically completed states.
*/
javax.transaction.xa.Xid[] recover(int i) throws javax.transaction.xa.XAException;
As is evident from the name of the method, the implementation is responsible for returning the Xid(s) which need to be recovered.
h1. XAResourceRecovery implementation for EJB client API
As explained in the JBoss Transactions document, the recovery process involves a background thread which runs at periodic intervals to check for transactions that should be recovered. From a EJB client API perspective, it has to know the target server against which it is issuing a recover request and also the node identifier of the node/server on which the (previously run) transaction(s) originated.
h2. Node identifier of the transaction origin
This is also known as the "parent node name". This is the node on which the transaction, which was propagated, originated. The transaction subsystem integration in AS7 exposes this node identifier via the CoreEnvironmentService:
package org.jboss.as.txn.service;
public class CoreEnvironmentService implements Service<CoreEnvironmentBean> {
...
}
package com.arjuna.ats.arjuna.common;
public class CoreEnvironmentBean implements CoreEnvironmentBeanMBean {
....
public String getNodeIdentifier() {
return nodeIdentifier;
}
So it's straightforward for the EJB client integration in AS7 to know what the node identifier of itself.
h2. Target server(s)/EJBReceiver(s) against which the recover request has to be issued
The EJBClientContext can potentially contain numerous EJBReceiver(s), each of which correspond to a different node. Furthermore, the EJBReceiver(s) within a EJBClientContext can be dynamic - which means at it may not always contain the same set of EJBReceiver(s). Certain receivers may be added or removed as and when such a need arises. As such, there's no fixed set of EJBReceiver(s) which the EJBClientContext can known before hand to issue the recovery request against. So how does the EJB client API know which EJBReceiver(s) should it issue the recovery request when the recovery manager background process asks it for the Xid[] that need to be recovered.
The answer to that question is that whenever a EJBReceiver is registered in a EJBClientContext, it will make that EJBReceiver eligible for issuing a recovery request against. This is a very important thing to remember since if a server/EJBReceiver was being used during EJB invocations and either the server or client crashed, then the recovery against the server/EJBReceiver will not be triggered unless that EJBReceiver gets registered within a EJBClientContext. This however isn't a restriction since a recovery process between 2 servers only makes sense when they are communicating with each other and from a EJB client API perspective, the communication can only happen when the EJBReceiver is registered in a EJBClientContext.
--------------------------------------------------------------
Comment by going to Community
[https://community.jboss.org/docs/DOC-48398]
Create a new document in JBoss AS 7 Development at Community
[https://community.jboss.org/choose-container!input.jspa?contentType=102&c...]
11 years, 10 months
[PicketBox Development] - secureResponse called before service invocation instead of after
by arjan tijms
arjan tijms [https://community.jboss.org/people/atijms] created the discussion
"secureResponse called before service invocation instead of after"
To view the discussion, visit: https://community.jboss.org/message/799210#799210
--------------------------------------------------------------
WebJASPIAuthenticator in JBoss AS 7.1.1 and JBoss EAP 6.0.1 calls +secureResponse+ right after +validateRequest+ on a SAM has been called. The only intermediate code is registering the result of the callback handler with the container. The service invocation (e.g. calling a Servlet) is done afterwards, ie after the call to +secureResponse+.
See the following fragment:
if (sam != null) {
result = sam.isValid(messageInfo, clientSubject, messageLayer, appContext, cbh);
}
// the authentication process has been a success. We need to register the principal, username, password and roles
// with the container
if (result) {
PasswordValidationCallback pvc = cbh.getPasswordValidationCallback();
CallerPrincipalCallback cpc = cbh.getCallerPrincipalCallback();
// get the client principal from the callback.
Principal clientPrincipal = cpc.getPrincipal();
if (clientPrincipal == null) {
clientPrincipal = new SimplePrincipal(cpc.getName());
}
// if the client principal is not a jboss generic principal, we need to build one before registering.
if (!(clientPrincipal instanceof JBossGenericPrincipal))
clientPrincipal = this.buildJBossPrincipal(clientSubject, clientPrincipal);
this.register(request, response, clientPrincipal, authMethod, pvc.getUsername(),
new String(pvc.getPassword()));
if (this.secureResponse)
sam.secureResponse(messageInfo, new Subject(), messageLayer, appContext, cbh);
}
However, section 3.8.3.3 of the JSR 196 (JASPIC) spec says that the semantics of secureResponse are as defined in Section 3.8.2.2, which thus means that secureResponse should be called +after+ a service invocation. Figure 1.1 in Section 1.1 shows this as well, and the general flow as described is Section 3.8 also mentions this.
So, in JBoss the sequence is
validateRequest -> secureResponse -> Invoke Service
While the spec seems to say it should be:
validateRequest -> Invoke Service -> secureResponse
In the reference implementation GlassFish the sequence is indeed the latter one.
--------------------------------------------------------------
Reply to this message by going to Community
[https://community.jboss.org/message/799210#799210]
Start a new discussion in PicketBox Development at Community
[https://community.jboss.org/choose-container!input.jspa?contentType=1&con...]
11 years, 10 months
[JBoss Web Development] - issues porting from websphere to JBoss AS7
by Praveen Gunda
Praveen Gunda [https://community.jboss.org/people/pgunda] created the discussion
"issues porting from websphere to JBoss AS7"
To view the discussion, visit: https://community.jboss.org/message/798986#798986
--------------------------------------------------------------
I have a Web application that uses JSP & Servlets. This is currently running on Websphere 7.1. We are trying to port to JBoss AS 7.1.1 in standalone mode to start with and am having issues.
The WAR deployed successfully and I get the home page (Static HTML)
Our application uses two files ibm-bnd-ext.xmi and ibm-web-ext.xmi .. These two files seem to be Websphere specific and detail the configuration of the JSP engine and Servlet engine.
*IBM-web-ext.xmi*
*
*
<?xml version="1.0" encoding="UTF-8"?>
<com.ibm.ejs.models.base.extensions.webappext:WebAppExtension xmi:version="2.0" xmlns:xmi=" http://www.omg.org/XMI http://www.omg.org/XMI" xmlns:com.ibm.ejs.models.base.extensions.webappext="webappext.xmi" xmi:id="WebAppExtension_1" reloadInterval="3" reloadingEnabled="true" additionalClassPath="" fileServingEnabled="true" directoryBrowsingEnabled="false" serveServletsByClassnameEnabled="true">
<webApp href="WEB-INF/web.xml#WebApp"/>
<jspAttributes xmi:id="JSPAttribute_1310946960877" name="reloadEnabled" value="true"/>
<jspAttributes xmi:id="JSPAttribute_1310946960878" name="reloadInterval" value="10"/>
</com.ibm.ejs.models.base.extensions.webappext:WebAppExtension>
*IBM-BND-EXT.xmi*
<?xml version="1.0" encoding="UTF-8"?>
<com.ibm.ejs.models.base.bindings.webappbnd:WebAppBinding xmi:version="2.0" xmlns:xmi=" http://www.omg.org/XMI http://www.omg.org/XMI" xmlns:com.ibm.ejs.models.base.bindings.webappbnd="webappbnd.xmi" xmi:id="WebAppBinding_1" virtualHostName="default_host">
<webapp href="WEB-INF/web.xml#WebApp"/>
</com.ibm.ejs.models.base.bindings.webappbnd:WebAppBinding>
*What is the equivalent configuration of these in JBoss?*
*Also, how do we enable Serve Servlets by Class Name in JBoss?*
*Any help is greatly appreciated...
*
--------------------------------------------------------------
Reply to this message by going to Community
[https://community.jboss.org/message/798986#798986]
Start a new discussion in JBoss Web Development at Community
[https://community.jboss.org/choose-container!input.jspa?contentType=1&con...]
11 years, 10 months
[jBPM Development] - Process instance execution do not continue to the next task after completing a previous task.
by Feki Ahmed
Feki Ahmed [https://community.jboss.org/people/bardelman] created the discussion
"Process instance execution do not continue to the next task after completing a previous task."
To view the discussion, visit: https://community.jboss.org/message/799100#799100
--------------------------------------------------------------
Hi,
i m using jbpm 5.4 embeded on a web application and i ve a problem after completing a task, getting the next task with the "getTasksAssignedAsPotentialOwner" do not return anything.
When i created the session which contain the process i registered a "LocalHTWorkItemHandler", so i don't think i need to complete it in order to the process to be continued.
After the task is completed , i checked on the database and found its status "completed" so i think nothing wrong have happened in completing/persisting operations.
i also don't have any exception and nothing happen in the application , i just can't get the next task.
h6. The following is the service java class which contain methods used for creating the session and completing the task.
public class JbpmAPIUtil {
public static StatefulKnowledgeSession ksession=null;
public static ProcessInstance processInstance;
public static List<LunchedProc> lunchedprocs = new ArrayList<LunchedProc>();
public static List<ProcessInstanceInfo> procsListfrmdb = new ArrayList<ProcessInstanceInfo>();
private static TaskService client;
/*
* Complete a task with a taskid and data for a user
*/
public static void completeTask(long taskId, Map<String,String> data, String userId){
UserTransaction ut=null;
try {
ut = (UserTransaction) new InitialContext().lookup( "java:comp/UserTransaction" );
} catch (NamingException e1) {
e1.printStackTrace();
}
try {
ut.begin();
} catch (NotSupportedException e) {
e.printStackTrace();
} catch (SystemException e) {
e.printStackTrace();
}
client.start(taskId, userId);
try {
ut.commit();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (HeuristicMixedException e) {
e.printStackTrace();
} catch (HeuristicRollbackException e) {
e.printStackTrace();
} catch (RollbackException e) {
e.printStackTrace();
} catch (SystemException e) {
e.printStackTrace();
}
ContentData contentData = null;
if (data != null) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out;
try {
out = new ObjectOutputStream(bos);
out.writeObject(data);
out.close();
contentData = new ContentData();
contentData.setContent(bos.toByteArray());
contentData.setAccessType(AccessType.Inline);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
ut.begin();
} catch (NotSupportedException e) {
e.printStackTrace();
} catch (SystemException e) {
e.printStackTrace();
}
client.complete(taskId, userId, contentData);
try {
ut.commit();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (HeuristicMixedException e) {
e.printStackTrace();
} catch (HeuristicRollbackException e) {
e.printStackTrace();
} catch (RollbackException e) {
e.printStackTrace();
} catch (SystemException e) {
e.printStackTrace();
}
}
private static StatefulKnowledgeSession CreateSession(String process){
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(new ClassPathResource(process), ResourceType.BPMN2);
if (kbuilder.hasErrors()) {
for (KnowledgeBuilderError error : kbuilder.getErrors()) {
System.out.println(">>> Error:" + error.getMessage());
}
System.out.println(">>> Knowledge couldn't be parsed! ");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
Environment env = EnvironmentFactory.newEnvironment();
EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.jbpm.runtime.ht");
env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());
// creating a Persistence Knowledge Session
System.out.println(" >>> Let's create a Persistent Knowledge Session");
final StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);
int sessionId = ksession.getId();
System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
System.out.println("sessionId : "+sessionId);
// We need to register the WorkItems and Listeners that the session will use
createTaskService(emf);
LocalHTWorkItemHandler localHTWorkItemHandler = new LocalHTWorkItemHandler(client, ksession);
ksession.getWorkItemManager().registerWorkItemHandler("Human Task", localHTWorkItemHandler);
KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);
return ksession;
}
private static void createTaskService(EntityManagerFactory emf) {
org.jbpm.task.service.TaskService taskService = new org.jbpm.task.service.TaskService(emf, SystemEventListenerFactory.getSystemEventListener());
Map<String, User> users = new HashMap<String, User>();
users.put("Administrator", new User("Administrator"));
users.put("user1", new User("user1"));
users.put("user2", new User("user2"));
Map<String, Group> groups = new HashMap<String, Group>();
taskService.addUsersAndGroups(users, groups);
client = new LocalTaskService(taskService);
}
}
Please , can someone guess what is wrong ??
--------------------------------------------------------------
Reply to this message by going to Community
[https://community.jboss.org/message/799100#799100]
Start a new discussion in jBPM Development at Community
[https://community.jboss.org/choose-container!input.jspa?contentType=1&con...]
11 years, 10 months