[
https://issues.apache.org/jira/browse/ODE-485?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Rafal Rusin closed ODE-485.
---------------------------
Resolution: Fixed
Sean Ahn resolved it in ode-564.
> Hang during startup
> -------------------
>
> Key: ODE-485
> URL: https://issues.apache.org/jira/browse/ODE-485
> Project: ODE
> Issue Type: Bug
> Components: JBI Integration
> Affects Versions: 1.3.2
> Environment: ServiceMix 3.3, Oracle DB Jencks Managed Connection, JPA
> Dao, EXTERNAL JNDI connection
> Reporter: Rafal Rusin
>
> I compiled ODE1x from branches, started it with 2 processes (2 SAs) and it
> hanged after loading one process (shutting down ServiceMix also hanged).
> Then I did some lookup and I saw that ConfStore DAO uses OpenJPA non managed
> db connections, while ProcessInstance DAO uses managed connections
> (openjpa.TransactionMode managed). This causes problem, since both of them
> use defined JNDI managed connection factory.
> So I added transacted SU deployment and it worked fine. The patch is
> following:
> Index: jbi/src/main/java/org/apache/ode/jbi/OdeSUManager.java
> ===================================================================
> --- jbi/src/main/java/org/apache/ode/jbi/OdeSUManager.java (revision 50556)
> +++ jbi/src/main/java/org/apache/ode/jbi/OdeSUManager.java (working copy)
> @@ -24,6 +24,8 @@
>
> import javax.jbi.component.ServiceUnitManager;
> import javax.jbi.management.DeploymentException;
> +import javax.transaction.SystemException;
> +import javax.transaction.TransactionManager;
> import javax.xml.parsers.DocumentBuilder;
> import javax.xml.parsers.DocumentBuilderFactory;
>
> @@ -49,202 +51,265 @@
> _ode = odeContext;
> }
>
> - public synchronized String deploy(String serviceUnitID, String
> serviceUnitRootPath) throws DeploymentException {
> - __log.trace("deploy: id=" + serviceUnitID + ", path=" +
> serviceUnitRootPath);
> + private interface TransactedDeployment {
> + public void transactedDeployment() throws DeploymentException;
> + }
> +
> + public synchronized String deploy(String serviceUnitID,
> + String serviceUnitRootPath) throws DeploymentException {
> + __log.trace("deploy: id=" + serviceUnitID + ", path="
> + + serviceUnitRootPath);
>
> - OdeServiceUnit su = new OdeServiceUnit(_ode, serviceUnitID,
> serviceUnitRootPath);
> - try {
> - su.deploy();
> - } catch (Exception ex) {
> - __log.error(__msgs.msgServiceUnitDeployFailed(serviceUnitID));
> - return makeStatusMessage("deploy", "FAILED");
> - }
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager())
> + .begin();
> + OdeServiceUnit su = new OdeServiceUnit(_ode,
> serviceUnitID,
> + serviceUnitRootPath);
> + su.deploy();
> + ((TransactionManager)
> _ode.getContext().getTransactionManager())
> + .commit();
> + } catch (Exception ex) {
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager())
> + .rollback();
> + } catch (Exception e) {
> + __log.debug("rollback failed", e);
> + }
> +
> __log.error(__msgs.msgServiceUnitDeployFailed(serviceUnitID));
> + return makeStatusMessage("deploy", "FAILED");
> + }
>
> - return makeStatusMessage("deploy", "SUCCESS");
> + return makeStatusMessage("deploy", "SUCCESS");
> + }
>
> - }
> + public synchronized void init(String serviceUnitID,
> + String serviceUnitRootPath) throws DeploymentException {
> + __log.trace("init called for " + serviceUnitID);
>
> - public synchronized void init(String serviceUnitID, String
> serviceUnitRootPath) throws DeploymentException {
> - __log.trace("init called for " + serviceUnitID);
> + if (_serviceUnits.containsKey(serviceUnitID)) {
> + __log.debug("odd, init() called for su " + serviceUnitID
> + + ", but it is already init()ed");
> + return;
> + }
>
> - if (_serviceUnits.containsKey(serviceUnitID)) {
> - __log.debug("odd, init() called for su " + serviceUnitID + ",
> but it is already init()ed");
> - return;
> - }
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).begin();
> + OdeServiceUnit su = new OdeServiceUnit(_ode,
> serviceUnitID,
> + serviceUnitRootPath);
> + su.init();
> + _serviceUnits.put(serviceUnitID, su);
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).commit();
> + } catch (Exception ex) {
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).rollback();
> + } catch (Exception e) {
> + __log.debug("rollback failed", e);
> + }
> + String errmsg =
> __msgs.msgServiceUnitInitFailed(serviceUnitID);
> + __log.error(errmsg, ex);
> + throw new DeploymentException(errmsg, ex);
> + }
> + }
>
> - try {
> - OdeServiceUnit su = new OdeServiceUnit(_ode, serviceUnitID,
> serviceUnitRootPath);
> - su.init();
> - _serviceUnits.put(serviceUnitID, su);
> - } catch (Exception ex) {
> - String errmsg = __msgs.msgServiceUnitInitFailed(serviceUnitID);
> - __log.error(errmsg, ex);
> - throw new DeploymentException(errmsg, ex);
> - }
> - }
> + public synchronized void shutDown(String serviceUnitID)
> + throws DeploymentException {
> + __log.trace("shutDown called for " + serviceUnitID);
>
> - public synchronized void shutDown(String serviceUnitID) throws
> DeploymentException {
> - __log.trace("shutDown called for " + serviceUnitID);
> + OdeServiceUnit su = _serviceUnits.remove(serviceUnitID);
> + if (su == null)
> + return;
>
> - OdeServiceUnit su = _serviceUnits.remove(serviceUnitID);
> - if (su == null)
> - return;
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).begin();
> + su.shutdown();
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).commit();
> + } catch (Exception ex) {
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).rollback();
> + } catch (Exception e) {
> + __log.debug("rollback failed", e);
> + }
> + String errmsg =
> __msgs.msgServiceUnitShutdownFailed(serviceUnitID);
> + __log.error(errmsg, ex);
> + throw new DeploymentException(errmsg, ex);
> + }
> + }
>
> - try {
> - su.shutdown();
> - } catch (Exception ex) {
> - String errmsg = __msgs.msgServiceUnitShutdownFailed(serviceUnitID);
> - __log.error(errmsg, ex);
> - throw new DeploymentException(errmsg, ex);
> - }
> - }
> + public synchronized void start(String serviceUnitID)
> + throws DeploymentException {
> + __log.trace("start called for " + serviceUnitID);
>
> - public synchronized void start(String serviceUnitID) throws
> DeploymentException {
> - __log.trace("start called for " + serviceUnitID);
> + OdeServiceUnit su = _serviceUnits.get(serviceUnitID);
> + if (su == null) {
> + // Should not really happen if JBI is working.
> + String errmsg = "Unexpected state; start() called
> before init()";
> + IllegalStateException ex = new
> IllegalStateException(errmsg);
> + __log.error(errmsg, ex);
> + throw new DeploymentException(errmsg, ex);
> + }
>
> - OdeServiceUnit su = _serviceUnits.get(serviceUnitID);
> - if (su == null) {
> - // Should not really happen if JBI is working.
> - String errmsg = "Unexpected state; start() called before init()";
> - IllegalStateException ex = new IllegalStateException(errmsg);
> - __log.error(errmsg, ex);
> - throw new DeploymentException(errmsg, ex);
> - }
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).begin();
> + su.start();
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).commit();
> + } catch (Exception ex) {
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).rollback();
> + } catch (Exception e) {
> + __log.debug("rollback failed", e);
> + }
> + String errmsg =
> __msgs.msgServiceUnitStartFailed(serviceUnitID);
> + __log.error(errmsg, ex);
> + throw new DeploymentException(errmsg, ex);
> + }
>
> - try {
> - su.start();
> - } catch (Exception ex) {
> - String errmsg = __msgs.msgServiceUnitStartFailed(serviceUnitID);
> - __log.error(errmsg, ex);
> - throw new DeploymentException(errmsg, ex);
> - }
> + }
>
> - }
> + /**
> + * Stop the deployment. This causes the component to cease generating
> service
> + * requests related to the deployment. This returns the deployment to a
> state
> + * equivalent to after init() was called
> + *
> + * @param serviceUnitID
> + * service unit ID
> + *
> + * @throws DeploymentException
> + * deployment exception
> + */
> + public synchronized void stop(String serviceUnitID)
> + throws DeploymentException {
> + __log.trace("stop called for " + serviceUnitID);
>
> - /**
> - * Stop the deployment. This causes the component to cease generating
> service
> - * requests related to the deployment. This returns the deployment to a
> state
> - * equivalent to after init() was called
> - *
> - * @param serviceUnitID
> - * service unit ID
> - *
> - * @throws DeploymentException
> - * deployment exception
> - */
> - public synchronized void stop(String serviceUnitID) throws
> DeploymentException {
> - __log.trace("stop called for " + serviceUnitID);
> + OdeServiceUnit su = _serviceUnits.get(serviceUnitID);
> + if (su == null) {
> + // Should not really happen if JBI is working.
> + String errmsg = "Unexpected state; stop() called before
> init()";
> + IllegalStateException ex = new
> IllegalStateException(errmsg);
> + __log.error(errmsg, ex);
> + throw new DeploymentException(errmsg, ex);
> + }
>
> - OdeServiceUnit su = _serviceUnits.get(serviceUnitID);
> - if (su == null) {
> - // Should not really happen if JBI is working.
> - String errmsg = "Unexpected state; stop() called before init()";
> - IllegalStateException ex = new IllegalStateException(errmsg);
> - __log.error(errmsg, ex);
> - throw new DeploymentException(errmsg, ex);
> - }
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).begin();
> + su.stop();
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).commit();
> + } catch (Exception ex) {
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).rollback();
> + } catch (Exception e) {
> + __log.debug("rollback failed", e);
> + }
> + String errmsg =
> __msgs.msgServiceUnitStopFailed(serviceUnitID);
> + __log.error(errmsg, ex);
> + throw new DeploymentException(errmsg, ex);
> + }
>
> - try {
> - su.stop();
> - } catch (Exception ex) {
> - String errmsg = __msgs.msgServiceUnitStopFailed(serviceUnitID);
> - __log.error(errmsg, ex);
> - throw new DeploymentException(errmsg, ex);
> - }
> + }
>
> - }
> + /**
> + * Cancel a Service Deployment. If the deployment is in use (has
> + * dependencies), then will operation may fail.
> + *
> + * @param serviceUnitID -
> + * ID of the Service Unit being undeployed
> + * @param serviceUnitRootPath -
> + * Full path to the Service Unit root.
> + *
> + * @return NOT YET DOCUMENTED
> + *
> + * @throws DeploymentException
> + * deployment exception
> + */
> + public synchronized String undeploy(String serviceUnitID,
> + String serviceUnitRootPath) throws DeploymentException {
> + __log.trace("undeploy: id=" + serviceUnitID + ", path="
> + + serviceUnitRootPath);
>
> - /**
> - * Cancel a Service Deployment. If the deployment is in use (has
> - * dependencies), then will operation may fail.
> - *
> - * @param serviceUnitID -
> - * ID of the Service Unit being undeployed
> - * @param serviceUnitRootPath -
> - * Full path to the Service Unit root.
> - *
> - * @return NOT YET DOCUMENTED
> - *
> - * @throws DeploymentException
> - * deployment exception
> - */
> - public synchronized String undeploy(String serviceUnitID, String
> serviceUnitRootPath) throws DeploymentException {
> - __log.trace("undeploy: id=" + serviceUnitID + ", path=" +
> serviceUnitRootPath);
> + OdeServiceUnit su = new OdeServiceUnit(_ode, serviceUnitID,
> + serviceUnitRootPath);
>
> - OdeServiceUnit su = new OdeServiceUnit(_ode, serviceUnitID,
> serviceUnitRootPath);
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).begin();
> + su.undeploy();
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).commit();
> + } catch (Exception ex) {
> + try {
> + ((TransactionManager)
> _ode.getContext().getTransactionManager()).rollback();
> + } catch (Exception e) {
> + __log.debug("rollback failed", e);
> + }
> +
> __log.error(__msgs.msgServiceUnitDeployFailed(serviceUnitID));
> + return makeStatusMessage("undeploy", "FAILED");
> + }
>
> - try {
> - su.undeploy();
> - } catch (Exception ex) {
> - __log.error(__msgs.msgServiceUnitDeployFailed(serviceUnitID));
> - return makeStatusMessage("undeploy", "FAILED");
> - }
> + return makeStatusMessage("undeploy", "SUCCESS");
>
> - return makeStatusMessage("undeploy", "SUCCESS");
> + }
>
> - }
> + /**
> + * Generate those lame XML result strings that JBI requires. Oh did I
> mention
> + * how lame this is? If not, let me remind the reader: this is just
> about the
> + * lamest "clever idea" I have ever seen.
> + *
> + * @param task
> + * the task that failed and must now generate a lame result
> string
> + * @param status
> + * the status code that will go into the lame result string.
> + * @return a lame JBI result string
> + */
> + private String makeStatusMessage(String task, String status) {
>
> - /**
> - * Generate those lame XML result strings that JBI requires. Oh did I
> mention
> - * how lame this is? If not, let me remind the reader: this is just about
> the
> - * lamest "clever idea" I have ever seen.
> - *
> - * @param task
> - * the task that failed and must now generate a lame result string
> - * @param status
> - * the status code that will go into the lame result string.
> - * @return a lame JBI result string
> - */
> - private String makeStatusMessage(String task, String status) {
> + /*
> + * Cheat sheet: <component-task-result>
> <component-name>BC1</component-name>
> + * <component-task-result-details
> + * xmlns="http://java.sun.com/xml/ns/jbi/management-
> <task-result-details>
> + * <task-id>deploy</task-id> <task-result>SUCCESS</task-result>
> + * </task-result-details> </component-task-result-details>
> + * </component-task-result>
> + *
> + */
>
> - /*
> - * Cheat sheet: <component-task-result>
> <component-name>BC1</component-name>
> - * <component-task-result-details
> - * xmlns="http://java.sun.com/xml/ns/jbi/management-
> <task-result-details>
> - * <task-id>deploy</task-id> <task-result>SUCCESS</task-result>
> - * </task-result-details> </component-task-result-details>
> - * </component-task-result>
> - *
> - */
> + // First of all, what is the logic why XML ? and if XML, why a
> String
> + // and not a DOM ? But the 64k question is what is wrong with
> Exceptions?
> + Document doc;
> + try {
> + // Note that we are using our own choice of factory
> (xerces), not the
> + // one that is provided by the system. This is
> important, otherwise the
> + // serialization routine won't work.
> + DocumentBuilderFactory dbf = XMLParserUtils
> + .getDocumentBuilderFactory();
> + DocumentBuilder db = dbf.newDocumentBuilder();
> + doc = db.newDocument();
> + } catch (Exception ex) {
> + throw new RuntimeException(ex);
> + }
>
> - // First of all, what is the logic why XML ? and if XML, why a String
> - // and not a DOM ? But the 64k question is what is wrong with Exceptions?
> - Document doc;
> - try {
> - // Note that we are using our own choice of factory (xerces), not the
> - // one that is provided by the system. This is important, otherwise
> the
> - // serialization routine won't work.
> - DocumentBuilderFactory dbf =
> XMLParserUtils.getDocumentBuilderFactory();
> - DocumentBuilder db = dbf.newDocumentBuilder();
> - doc = db.newDocument();
> - } catch (Exception ex) {
> - throw new RuntimeException(ex);
> - }
> + Element elem = doc.createElement("component-task-result");
> + doc.appendChild(elem);
> + Element compNameElem = doc.createElement("component-name");
> + elem.appendChild(compNameElem);
> + Element compTaskRsltDtlsElem = doc
> + .createElement("component-task-result-details");
> + elem.appendChild(compTaskRsltDtlsElem);
> + Element taskRsltDtlsElem =
> doc.createElement("task-result-details");
> + compTaskRsltDtlsElem.appendChild(taskRsltDtlsElem);
>
> - Element elem = doc.createElement("component-task-result");
> - doc.appendChild(elem);
> - Element compNameElem = doc.createElement("component-name");
> - elem.appendChild(compNameElem);
> - Element compTaskRsltDtlsElem =
> doc.createElement("component-task-result-details");
> - elem.appendChild(compTaskRsltDtlsElem);
> - Element taskRsltDtlsElem = doc.createElement("task-result-details");
> - compTaskRsltDtlsElem.appendChild(taskRsltDtlsElem);
> + Element taskId = doc.createElement("task-id");
> + taskRsltDtlsElem.appendChild(taskId);
>
> - Element taskId = doc.createElement("task-id");
> - taskRsltDtlsElem.appendChild(taskId);
> + Element taskResult = doc.createElement("task-result");
> + taskRsltDtlsElem.appendChild(taskResult);
>
> - Element taskResult = doc.createElement("task-result");
> - taskRsltDtlsElem.appendChild(taskResult);
> + // Why do I have to tell this thing the component name? It
> /knows/ the
> + // component name....
> + compNameElem.appendChild(doc.createTextNode(_ode.getContext()
> + .getComponentName()));
>
> - // Why do I have to tell this thing the component name? It /knows/ the
> - // component name....
> -
> compNameElem.appendChild(doc.createTextNode(_ode.getContext().getComponentName()));
> + // And why on earth do I have to tell my caller the method he
> just
> + // called?
> + taskId.appendChild(doc.createTextNode(task));
>
> - // And why on earth do I have to tell my caller the method he just
> - // called?
> - taskId.appendChild(doc.createTextNode(task));
> -
> - taskResult.appendChild(doc.createTextNode(status));
> - return DOMUtils.domToString(elem);
> - }
> + taskResult.appendChild(doc.createTextNode(status));
> + return DOMUtils.domToString(elem);
> + }
> }
> Index:
> bpel-store/src/main/java/org/apache/ode/store/jpa/DbConfStoreConnectionFactory.java
> ===================================================================
> ---
> bpel-store/src/main/java/org/apache/ode/store/jpa/DbConfStoreConnectionFactory.java
> (revision 50557)
> +++
> bpel-store/src/main/java/org/apache/ode/store/jpa/DbConfStoreConnectionFactory.java
> (working copy)
> @@ -39,6 +39,8 @@
> _ds = ds;
> HashMap propMap = new HashMap();
> propMap.put("javax.persistence.jtaDataSource", ds);
> + propMap.put("openjpa.TransactionMode", "managed");
> + propMap.put("openjpa.ManagedRuntime",
> "jndi(TransactionManagerName=java:/TransactionManager)");
> propMap.put("openjpa.Log", "log4j");
> // propMap.put("openjpa.jdbc.DBDictionary",
> "org.apache.openjpa.jdbc.sql.DerbyDictionary");
> if (createDatamodel) propMap.put("openjpa.jdbc.SynchronizeMappings",
> "buildSchema(ForeignKeys=false)");
> Index: bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java
> ===================================================================
> --- bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java
> (revision 50556)
> +++ bpel-store/src/main/java/org/apache/ode/store/ProcessStoreImpl.java
> (working copy)
> @@ -73,7 +73,7 @@
> */
> public class ProcessStoreImpl implements ProcessStore {
>
> - private static final Log __log =
> LogFactory.getLog(ProcessStoreImpl.class);
> + private static final Log __log =
> LogFactory.getLog(ProcessStoreImpl.class);
>
> private static final Messages __msgs =
> MessageBundle.getMessages(Messages.class);
>
> @@ -100,7 +100,7 @@
> * to get confused ii) we're already serializing all the operations with
> a read/write lock. iii) we don't care about
> * performance, these are infrequent operations.
> */
> - private ExecutorService _executor =
> Executors.newSingleThreadExecutor(new SimpleThreadFactory());
> + //private ExecutorService _executor =
> Executors.newSingleThreadExecutor(new SimpleThreadFactory());
>
> /**
> * In-memory DataSource, or <code>null</code> if we are using a real DS.
> We need this to shutdown the DB.
> @@ -161,6 +161,8 @@
> super.finalize();
> }
>
> +
> +
> /**
> * Deploys a process.
> */
> @@ -546,12 +548,13 @@
> synchronized <T> T exec(Callable<T> callable) {
> // We want to submit db jobs to an executor to isolate
> // them from the current thread,
> - Future<T> future = _executor.submit(callable);
> - try {
> - return future.get();
> - } catch (Exception e) {
> - throw new ContextException("DbError", e);
> - }
> + return callable.call();
> +// Future<T> future = _executor.submit(callable);
> +// try {
> +// return future.get();
> +// } catch (Exception e) {
> +// throw new ContextException("DbError", e);
> +// }
> }
>
> private ConfStoreConnection getConnection() {
> @@ -703,28 +706,33 @@
> */
> abstract class Callable<V> implements java.util.concurrent.Callable<V> {
> public V call() {
> - boolean success = false;
> - ConfStoreConnection conn = getConnection();
> - try {
> - conn.begin();
> - V r = call(conn);
> - conn.commit();
> - success = true;
> - return r;
> - } finally {
> - if (!success)
> - try {
> - conn.rollback();
> - } catch (Exception ex) {
> - __log.error("DbError", ex);
> - }
> - try {
> - conn.close();
> - } catch (Exception ex) {
> - __log.error("DbError", ex);
> - }
> - }
> -
> + return call(getConnection());
> +// boolean success = false;
> +// ConfStoreConnection conn = getConnection();
> +// try {
> +// try {
> +// conn.begin();
> +// V r = call(conn);
> +// conn.commit();
> +// success = true;
> +// return r;
> +// } finally {
> +// if (!success)
> +// try {
> +// conn.rollback();
> +// } catch (Exception ex) {
> +// __log.error("DbError", ex);
> +// }
> +// try {
> +// conn.close();
> +// } catch (Exception ex) {
> +// __log.error("DbError", ex);
> +// }
> +// }
> +// } catch (Exception e) {
> +// __log.fatal("Error in transaction ", e);
> +// return null;
> +// }
> }
>
> abstract V call(ConfStoreConnection conn);
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.