[jboss-jira] [JBoss JIRA] Created: (EJBTHREE-917) Cannot deploy ear with log-jars in isolated mode
Oskar Carlstedt (JIRA)
jira-events at lists.jboss.org
Mon Mar 19 04:32:59 EDT 2007
Cannot deploy ear with log-jars in isolated mode
------------------------------------------------
Key: EJBTHREE-917
URL: http://jira.jboss.com/jira/browse/EJBTHREE-917
Project: EJB 3.0
Issue Type: Bug
Affects Versions: EJB 3.0 RC9 - Patch 1
Environment: JBoss 4.0.5.GA with JBossWs 1.2.0 SP1, Windows Vista Enterprise Ed. (Possible all)
Reporter: Oskar Carlstedt
Hello!!
This is a short summary of my post at your forum http://www.jboss.org/index.html?module=bb&op=viewtopic&t=104337. I don't know if to place this in the EKB3 project or in the AS project. Maybe it belongs to the AS project.
Deploying below EAR file gives an error telling me "EJBLocal is not visible..."
A std. EAR file can contain a jar file that are used by the EJB- and web modules packed within the EAR file. Doing this with an EAR containing a war file having JAX-WS web service and a jar file containing a simple stateless Session bean. I run JBoss 4.0.5.GA in isolated mode.
My EAR file looks like:
Code:
my-test-ear
beans.jar (having a MANIFEST.MF file with classpath pointing to lib/...)
jaxws-web.war (having a MANIFEST.MF with classpath pointing to lib/...)
/lib
log4j.jar
commons-logging.jar
xbean.jar
xmlpublic.jar
saxon.jar
...
/META-INF
application.xml
MANIFEST.MF
jboss-app.xml (containing a loader-repository-tag with valie my-ear:app=ejb3)
************ application.xml ****************
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/application_1_4.xsd" version="1.4">
<description>my-test</description>
<display-name>my-test</display-name>
<module>
<ejb>my-test-beans.jar</ejb>
</module>
<module>
<web>
<web-uri>my-test-jaxws-web.war</web-uri>
<context-root>/my-test-jaxws-web</context-root>
</web>
</module>
</application>
************** jboss-app.xml *****************
<!DOCTYPE jboss-app
PUBLIC "-//JBoss//DTD J2EE Application 1.4//EN"
"http://www.jboss.org/j2ee/dtd/jboss-app_4_0.dtd">
<jboss-app>
<loader-repository>my-test:app=ejb3</loader-repository>
</jboss-app>
Here is the contents of my beans.jar:
Code:
my-test-beans.jar
META-INF
MANIFEST.MF
maven
my-test
my-test-beans
pom.xml
pom.properties
my
beans
TestBean.class
***************** TestBean.java ****************
package my.test;
import javax.ejb.Stateless;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlbeans.XmlObject;
@Stateless
public class TestBean implements Test {
/**
* Declare a logger to use in this class
*/
private final static Log log = LogFactory.getLog(TestBean.class);
public XmlObject doSomething(XmlObject theRequestXmlObject) {
return theRequestXmlObject;
}
}
******************* Test.java *********************
package my.test;
public interface Test {
public org.apache.xmlbeans.XmlObject doSomething(org.apache.xmlbeans.XmlObject theRequestXmlObje
ct);
}
And here is what my war fil looks like
Code:
my-test-jaxws-web.war
META-INF
MANIFEST.MF
maven
my-test
my-test-jaxws-web
pom.xml
pom.properties
WEB-INF
wsdl
test.wsdl
test.xsd
classes
my
test
TestServiceEnpoint.class
web.xml
********************** TestServiceEndpoint.java ******************
package my.test;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.naming.InitialContext;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.handler.MessageContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.w3c.dom.Node;
@Stateless
@WebServiceProvider(
serviceName = "Test",
portName = "TestSoap11Port",
targetNamespace = "http://my-test/service",
wsdlLocation = "WEB-INF/wsdl/test.wsdl")
@ServiceMode(value = Service.Mode.PAYLOAD)
public class TestServiceEndpoint implements Provider<Source> {
/**
* Declare a logger to use
*/
private final static Log log = LogFactory.getLog(TestServiceEndpoint.class);
/**
* The sei to use
*/
private Object sei = null;
/**
* The soapaction http header. Just a string with the value 'soapaction'
*/
private static final String HTTP_HEADER_SOAP_ACTION = "soapaction";
@Resource
protected WebServiceContext webServiceContext;
/**
* Does everything that must be done. This method is a kind of dispatcher
* that finds the business method to invoke. Invokes the method and
* serializes the response.
*/
public Source invoke(Source requestSource) {
try {
// get transformer and set output to xml
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
// holder of encoding, used in debug
String encoding = null;
// get everything as a dom result
DOMResult domResult = new DOMResult();
transformer.transform(requestSource, domResult);
// get dom node from dom result
Node domNode = domResult.getNode();
// let xml beans parse the dom node
XmlObject xmlRequestObject = XmlObject.Factory.parse(domNode);
if (log.isDebugEnabled()) {
// get everything as a stream result
ByteArrayOutputStream outTmpStream = new ByteArrayOutputStream();
StreamResult streamResult = new StreamResult();
streamResult.setOutputStream(outTmpStream);
// transform everything into the out stream
transformer.transform(requestSource, streamResult);
// get encoding of incomming request, default to utf-8
String tmpContent = new String(outTmpStream.toByteArray());
String encodingStartToken = "encoding=\"";
String encodingEndToken = "\"";
int encodingStart = tmpContent.indexOf(encodingStartToken);
if(encodingStart != -1) {
// get end index of encoding
encodingStart = encodingStart + encodingStartToken.length();
int encodingEnd = tmpContent.indexOf(encodingEndToken, encodingStart);
// set new encoding
encoding = tmpContent.substring(encodingStart, encodingEnd);
}
else {
// default encoding is UTF-8
encoding = "UTF-8";
}
// get a string reppresentation of incomming request
String xmlRequestString = new String(outTmpStream.toByteArray(), encoding);
log.debug("Incomming request:\n" + xmlRequestString);
}
// instantiate the sei
InitialContext initialContext = new InitialContext();
sei = initialContext.lookup("my-test/TestBean/local");
// get business method
Method wsdlJavaMethod = getWsdlJavaMethod();
// invoke method
XmlObject xmlResponseObject = (XmlObject) wsdlJavaMethod.invoke(sei, xmlRequestObject);
// if debug, debug response
if(log.isDebugEnabled()) {
// create xml options
XmlOptions xmlOptions = new XmlOptions();
xmlOptions.setSavePrettyPrint();
xmlOptions.setSavePrettyPrintIndent(4);
xmlOptions.setUseDefaultNamespace();
// creat a byte arry stream where to print result
ByteArrayOutputStream tmpStream = new ByteArrayOutputStream();
xmlResponseObject.save(tmpStream, xmlOptions);
// debug result
log.debug("Outgoing response:\n" + new String(tmpStream.toByteArray(), encoding));
}
// return the object
return new DOMSource(xmlResponseObject.newDomNode());
} catch (RuntimeException re) {
throw re;
} catch (Exception e) {
throw new WebServiceException(e);
}
}
private Method getWsdlJavaMethod() {
// get message context
MessageContext messageContext = webServiceContext.getMessageContext();
// get request headers from message context
Map<String, ?> requestHeaders = (Map<String, ?>) messageContext
.get(MessageContext.HTTP_REQUEST_HEADERS);
// get soap action header
List<String> soapactions = (List<String>) requestHeaders
.get(HTTP_HEADER_SOAP_ACTION);
// ceck soapaction assertions
if (soapactions == null || soapactions.size() != 1) {
// one soapaction must be given per each request
throw new WebServiceException(
"...");
}
// get soapaction
String soapaction = soapactions.get(0);
log.debug("Got soapaction httpheader: " + soapaction);
// extract method name
String methodName = extractJavaMethodName(soapaction);
log.debug("Extracted method name from soapaction: " + methodName);
// get the method to invoke
Method wsdlJavaMethod;
try {
wsdlJavaMethod = sei.getClass().getMethod(methodName, new Class<?>[]{XmlObject.class});
// return the found method
return wsdlJavaMethod;
} catch (SecurityException e) {
throw new RuntimeException("...", e);
} catch (NoSuchMethodException e) {
throw new RuntimeException("..." xmlObject)", e);
}
}
/**
* Returns the java method name extracted from a given soap action string.
* This method does not validate the returned value, it just extracts a
* possible java method name.
*
* @param soapaction
* the soap action to extract method from
* @return a java method name
*/
private String extractJavaMethodName(String soapaction) {
String methodName = null;
if(soapaction.indexOf(":") != -1) {
// get part of soapaction after the ':'-character
methodName = soapaction.substring(soapaction.lastIndexOf(":") + 1);
}
else {
// no ':'-character. method name is same as soapaction
methodName = soapaction;
}
// remove trailing cite character and then return
return methodName.substring(0, methodName.length() - 1);
}
}
When I deploy the war file itself (but then having all the dependencies in the WEB-INF/lib folder, that part works. But putting EJB3s and WARs together in an EAR file seems to be a problem.
Deploying the same file again, but without the jars log4j and commons-logging. Wolla!!, It seems to work.
Is this a classloader bug/error? What I mean is. The files I put in my ear are those I want to use, especially in isolated mode. As far as i know it shall not matter if a put a log4j jar in my ear, it shall override the one in the server/default/lib folder. I think this is very important when delivering ready to install archives (an archive I can send to a customer just telling him "drop the ear in the deploy folder and that's it").
After investigation this, I realized the problem is even worse. If I deploy my EAR file with the log4j and commons-logging jars bundled, then I must restart JBoss to be able to deploy the new ear without my logging jars.
Best Regards
Oskar Carlstedt
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the jboss-jira
mailing list