Having trouble mocking an email server using JUnit - email

I'm trying to mock sending an email (for the purposes of JUnit, v4.8.1, testing) and decided to use Dumbster, which I found through SO. I'm using version 1.6. I have this in my JUnit test …
SimpleSmtpServer server = SimpleSmtpServer.start();
boolean ret = m_emailSvc.sendEmail("me#me.com",
"you#you.com",
"localhost",
"Test",
"Test Body");
Assert.assertTrue(ret);
server.stop();
and I send an email this way …
public boolean sendEmail(final String toEmail,
final String fromEmail,
final String smtpHost,
final String subject,
final String body)
{
boolean ret = true;
// Get system properties
Properties properties = System.getProperties();
// Setup mail server
properties.setProperty("mail.smtp.host", smtpHost);
// Get the default Session object.
Session session = Session.getDefaultInstance(properties);
try{
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(fromEmail));
// Set To: header field of the header.
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(toEmail));
// Set Subject: header field
message.setSubject(subject);
// Now set the actual message
message.setText(body);
// Send message
Transport.send(message);
}catch (MessagingException mex) {
ret = false;
LOG.error(mex.getMessage(), mex);
} // try
return ret;
} // sendEmail
This fails with the exception below. Does anyone know what I'm doing wrong or is there an easier way to mock sending an email in a JUnit test?
java.net.BindException: Permission denied
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.socketBind(PlainSocketImpl.java:521)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:414)
at java.net.ServerSocket.bind(ServerSocket.java:326)
at java.net.ServerSocket.<init>(ServerSocket.java:192)
at java.net.ServerSocket.<init>(ServerSocket.java:104)
at com.dumbster.smtp.SimpleSmtpServer.run(Unknown Source)
at java.lang.Thread.run(Thread.java:680)
[ERROR]: org.mainco.subco.email.service.EmailServiceImpl - Could not connect to SMTP host: localhost, port: 25
javax.mail.MessagingException: Could not connect to SMTP host: localhost, port: 25;
nested exception is:
java.net.ConnectException: Connection refused
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1934)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:638)
at javax.mail.Service.connect(Service.java:295)
at javax.mail.Service.connect(Service.java:176)
at javax.mail.Service.connect(Service.java:125)
at javax.mail.Transport.send0(Transport.java:194)
at javax.mail.Transport.send(Transport.java:124)
at org.mainco.subco.email.service.EmailServiceImpl.sendEmail(EmailServiceImpl.java:62)
at org.mainco.subco.email.service.EmailServiceTest.testSendEmail(EmailServiceTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:382)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:241)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:228)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
at java.net.Socket.connect(Socket.java:527)
at java.net.Socket.connect(Socket.java:476)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:288)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:231)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1900)

I decided to mock the static call from the Transport class instead, using PowerMock (v.1.5.1).
#RunWith(PowerMockRunner.class)
public class EmailServiceTest
{
#Autowired
private EmailService m_emailSvc = new EmailServiceImpl();
#Test
#PrepareForTest( Transport.class )
public final void testSendEmail()
{
suppress(methodsDeclaredIn(Transport.class));
boolean ret = m_emailSvc.sendEmail("me#me.com",
"you#you.com",
"localhost",
"Test",
"Test Body");
Assert.assertTrue(ret);
} // testSendEmail

What about wrapping the call to Transport is a mockable object? Inject the mock and verify the call.
What I mean is something like this...
class MyTransport{
public void send(MimeMessage message){
Transport.send(message);
}
}
Then inject an instance of this class into your class above. In your production env you have the same code. However, when doing testing you could pass in a Mock for MyTransport and thereby verify the call to send without the need of a server.

Related

How to catch SOAP request message in CXF with WSS4JOutInterceptor when connection fails

I can catch SOAP request message according to
this SO answer.
However if the server is unavailable I get the following exception from SAAJOutInterceptor (added by WSS4JOutInterceptor) and LoggingCallback is not invoked hence message is not caugth:
org.apache.cxf.binding.soap.SoapFault: Connection refused: connect
at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:221)
at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:174)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:531)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:440)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:355)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:313)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140)
...
Caused by: com.ctc.wstx.exc.WstxIOException: Connection refused: connect
at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:262)
at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:215)
...
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
at sun.net.www.http.HttpClient.New(HttpClient.java:339)
at sun.net.www.http.HttpClient.New(HttpClient.java:357)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1199)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:274)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1345)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1306)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:307)
at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
at org.apache.cxf.io.AbstractThresholdOutputStream.unBuffer(AbstractThresholdOutputStream.java:89)
at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:63)
at org.apache.cxf.io.CacheAndWriteOutputStream.write(CacheAndWriteOutputStream.java:80)
at org.apache.cxf.io.CacheAndWriteOutputStream.write(CacheAndWriteOutputStream.java:80)
at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:51)
at com.ctc.wstx.io.UTF8Writer.flush(UTF8Writer.java:100)
at com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:242)
at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:260)
...
I need to save request SOAP message with all the security stuff added by WSS4JOutInterceptor (certificate, signature ...) regardless of whether the message was successfully send or whether the server is even up.
The thing is that you must first write to the output stream where you catch the message and write to network connection only in onClose callback:
class RequestInterceptor extends AbstractPhaseInterceptor<Message> {
OutputStream outputStream
OutputStream originalOutputStream
public RequestInterceptor() {
super(Phase.PRE_STREAM);
}
#Override
public void handleMessage(Message message) throws Fault {
originalOutputStream = message.getContent(OutputStream.class)
CacheAndWriteOutputStream newOutputStream = new CacheAndWriteOutputStream(outputStream)
message.setContent(OutputStream.class, newOutputStream)
newOutputStream.registerCallback(new CachedOutputStreamCallback() {
void onFlush(CachedOutputStream cos) {
}
void onClose(CachedOutputStream cos) {
cos.writeCacheTo(originalOutputStream)
originalOutputStream.close()
}
})
}
}

Hazelcast need to be connected as client in the existing cluster instead of member

The changes which I made in server side:
#Bean(name = {"hazelcast"})
public HazelcastInstance hazelcastInstance() {
ClientConfig clientConfig = new ClientConfig();
clientConfig.getGroupConfig().setName(integrationSettings.getHazelcastClusterGroupName())
.setPassword(integrationSettings.getHazelcastClusterGroupPass());
final ClientNetworkConfig clientNetworkConfig = new ClientNetworkConfig();
clientNetworkConfig.addAddress("127.0.0.1:6701");
clientConfig.setNetworkConfig(clientNetworkConfig);
clientConfig.setInstanceName("INTEGRATION_INSTANCE");
final String hazelcastEnterpriseLicenseKey = null;
if (hazelcastEnterpriseLicenseKey != null) {
clientConfig.setLicenseKey(hazelcastEnterpriseLicenseKey);
}
return HazelcastClient.newHazelcastClient(clientConfig);
}
I will be getting my groupname and password from my property file.
My client side code:
ClientConfig clientConfig = new ClientConfig();
clientConfig.getGroupConfig().setName(hazelcastGroupName).setPassword(hazelcastGroupPwd);
clientConfig.getNetworkConfig().addAddress(serverAddress);
hazelcastInstance = HazelcastClient.newHazelcastClient(clientConfig);
My error log:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.hazelcast.core.HazelcastInstance]: Factory method 'hazelcastInstance' threw exception; nested exception is java.lang.IllegalStateException: Unable to connect to any address in the config! The following addresses were tried: [[127.0.0.1]:6701]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
... 37 more
Caused by: java.lang.IllegalStateException: Unable to connect to any address in the config! The following addresses were tried: [[127.0.0.1]:6701]
at com.hazelcast.client.spi.impl.ClusterListenerSupport.connectToCluster(ClusterListenerSupport.java:178)
at com.hazelcast.client.spi.impl.ClientClusterServiceImpl.start(ClientClusterServiceImpl.java:189)
at com.hazelcast.client.impl.HazelcastClientInstanceImpl.start(HazelcastClientInstanceImpl.java:404)
at com.hazelcast.client.HazelcastClientManager.newHazelcastClient(HazelcastClientManager.java:78)
at com.hazelcast.client.HazelcastClient.newHazelcastClient(HazelcastClient.java:72)
at com.zafin.zrpe.integration.config.ZrpeIntegrationConfiguration.hazelcastInstance(ZrpeIntegrationConfiguration.java:85)
at com.zafin.zrpe.integration.config.ZrpeIntegrationConfiguration$$EnhancerBySpringCGLIB$$7af6798e.CGLIB$hazelcastInstance$6(<generated>)
at com.zafin.zrpe.integration.config.ZrpeIntegrationConfiguration$$EnhancerBySpringCGLIB$$7af6798e$$FastClassBySpringCGLIB$$25f010cb.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
at com.zafin.zrpe.integration.config.ZrpeIntegrationConfiguration$$EnhancerBySpringCGLIB$$7af6798e.hazelcastInstance(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 38 more
I need to connect my hazelcast as a client, but this bean exception is failing the deployments. Is there is any other way of doing it?
Looking at your code you are creating "Hazelcast-Client" on the server side and Client Side. In the server side code , please create a hazelcast ServerMember instance by passing "Config" object and not "ClientConfig" more like
#Bean
public HazelcastInstance hazelcastInstance() throws Exception {
Config cfg = new Config();
...
...
HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);
return instance;
}
The the Hazelcast-client can connect to the Hazelcast ServerMember. You also need to ensure the ServerMember is started before client can connect to it.

Cannot send request to MQSeries service

Im trying to send request with such code
import com.ibm.mq.jms.*;
import com.ibm.msg.client.wmq.WMQConstants;
import javax.jms.Session;
import javax.jms.TextMessage;
public class MQSend {
public static void main(String[] args)
{
try {
MQQueueConnectionFactory cf = new MQQueueConnectionFactory();
cf.setHostName("blabla");
cf.setPort(15000);
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setQueueManager("");
cf.setChannel("blabla");
MQQueueConnection connection = (MQQueueConnection) cf.createQueueConnection("blabla","blabla");
MQQueueSession session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
MQQueue queue = (MQQueue) session.createQueue("blabla");
MQQueueSender sender = (MQQueueSender) session.createSender(queue);
long uniqueNumber = System.currentTimeMillis() % 1000;
TextMessage message = (TextMessage) session.createTextMessage("Basic Queue Test "+ uniqueNumber);
// Start the connection
connection.start();
// sender.send(message);
System.out.println("Sent message to Queue MyTestQueue: " + message.getText());
// sender.close();
session.close();
connection.close();
System.out.println("Message Sent OK.\n");
}
catch (Exception ex) {
System.out.println(ex);
System.out.println("Message Send Failure\n");
}
}
}
I got
Exception in thread "main" java.lang.NoClassDefFoundError: com/ibm/msg/client/commonservices/trace/Trace
at com.ibm.msg.client.jms.internal.JmsReadablePropertyContextImpl.<clinit>(JmsReadablePropertyContextImpl.java:51)
at com.hsbc.hbfr.test.automation.tools.jrb.plugins.itm.MQSend.main(MQSend.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.ClassNotFoundException: com.ibm.msg.client.commonservices.trace.Trace
So issue is that java can't get appropriate jar for com/ibm/msg/client/commonservices/trace/Trace
But I even don't use such dependency in code, any suggestions?
thanks
Did you install MQ Client on the server? Did you put ALL of the MQ jar files in the CLASSPATH as per the docs? Looks like you missed at least one.

How to resolve a Classloader related 'java.lang.LinkageError' when sending email from Tomee?

I am trying to send an email from my code that runs on Tomee 1.6
I have the following entry in the tomee.xml file.
<Resource
id="abc_mail"
type="javax.mail.Session"
>
mail.transport.protocol=smtp
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
mail.smtp.socketFactory.fallback=false
mail.smtp.host=smtp.gmail.com
mail.smtp.port=465
mail.smtp.auth=true
mail.smtp.user=xyz#gmail.com
password=xyzpass
</Resource>
I have an ejb with the following declaration.
#Resource(name = "abc_mail")//, type = javax.mail.Session.class)
Session abcMailSession;
The code for sending the email is the following.
public void sendMessage(String addressTo, String subject, String messageText) {
try {
Message message = new MimeMessage(abcMailSession);
message.setFrom(new InternetAddress("abc#xyz.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(addressTo));
message.setSubject(subject);
message.setText(messageText);
Transport.send(message);
logger.info("Message sent successfully.");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
When calling this method I get the following error.
Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "org.apache.geronimo.mail.util.SessionUtil.getBooleanProperty(Ljavax/mail/Session;Ljava/lang/String;Z)Z" the class loader (instance of org/apache/openejb/util/classloader/URLClassLoaderFirst) of the current class, javax/mail/internet/MimeMessage, and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for resolved class, org/apache/geronimo/mail/util/SessionUtil, have different Class objects for the type vax/mail/Session;Ljava/lang/String;Z)Z used in the signature
at javax.mail.internet.MimeMessage.isStrictAddressing(MimeMessage.java:1460)
at javax.mail.internet.MimeMessage.addRecipientsToList(MimeMessage.java:428)
at javax.mail.internet.MimeMessage.getAllRecipients(MimeMessage.java:400)
at javax.mail.Transport.send(Transport.java:48)
at co.uk.dakia.core.interfaces.impl.NotificationManagerImpl.sendMessage(NotificationManagerImpl.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:182)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:164)
at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:180)
at org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:99)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:182)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:164)
at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:80)
at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:212)
at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:181)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:268)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:263)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:86)
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:303)
... 47 more
Why do I get this error? I am not able to figure out the first line in the stack trace.
I have now solved this. The error occurs because the same class is being loaded by two different classloaders (tomcat and openejb ones), the class in question is javax.mail.Session
I added the following property to tomee's system.properties file
openejb.classloader.forced-skip=javax.mail
What this does it prevents openejb classloader from loading the javax.mail classes and therefore only tomcat classloader loads all the relevant classes required for sending email.

GWT Throwing exception to client

Can someone show to throw exception to client in GWT.
in my serviceasync interface i am doing this as well in my service interface
void ActivateUserAccount(String ActivationCode,AsyncCallback <Boolean> Callback) throws AlreadyActivatedError;
in my serverimpl;
i am doing this to throw an exception
public Boolean ActivateUserAccount(String ActivationCode) throws AlreadyActivatedError
{
....
throw new AlreadyActivatedError();
}
my exception is in the form:
public class AlreadyActivatedError extends Exception implements IsSerializable
{
public AlreadyActivatedError()
{
super();
}
}
Just to make everything clear: you can throw both checked (the ones extending Exception) and unchecked (extending RuntimeException) exceptions from the server to the client - as long as the exception is serializable. It is however recommended to throw checked exceptions, as they
represent invalid conditions in areas outside the immediate control of the program (invalid user input, database problems, network outages, absent files).
In contrast, unchecked exceptions
represent defects in the program (bugs) - often invalid arguments passed to a non-private method.
Source
As the documentation states, the following conditions have to be fulfilled for an exception to be sent to the client:
It has to extend Exception (note that RuntimeException does that).
It has to be serializable. In short: implement Serializable, have a no-args constructor and have all the fields serializable.
In your *Service interface you need to add a throws declaration to the method that can throw the exception. Note that you don't need to add the throws declaration to the *Async interface.
Once you have that set up, you'll be able to handle the exception in the onFailure method in your AsyncCallback.
Some code to show all the pieces together, based on examples from the guide on the GWT site:
DelistedException.java
public class DelistedException extends Exception implements Serializable {
private String symbol;
// Note the no-args constructor
// It can be protected so that only subclasses could use it
// (because if they want to be serializable too, they'll need
// a no-args constructor that calls the superclasses' no-args constructor...)
protected DelistedException() {
}
public DelistedException(String symbol) {
this.symbol = symbol;
}
public String getSymbol() {
return this.symbol;
}
}
StockPriceService.java
#RemoteServiceRelativePath("stockPrices")
public interface StockPriceService extends RemoteService {
StockPrice[] getPrices(String[] symbols) throws DelistedException;
}
StockPriceServiceAsync.java
public interface StockPriceServiceAsync {
void getPrices(String[] symbols, AsyncCallback<StockPrice[]> callback);
}
On the client side
AsyncCallback<StockPrice[]> callback = new AsyncCallback<StockPrice[]>() {
public void onFailure(Throwable caught) {
if (caught instanceof DelistedException) {
// Do something with it
} else {
// Probably some unchecked exception,
// show some generic error message
}
public void onSuccess(StockPrice[] result) {
// Success!
}
};
stockPriceService.getPrices(symbols, callback);
Not sure why hilal's answer was accepted as it is completely false.
In order for the exceptions to reach the client's browser you must throw a checked exception that is Serializable and defined in the service interfaces.
If your service implementation throws a RuntimeException the web client will receive a generic 500 error messages as follows:
[WARN] Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract my.module.shared.Result my.module.client.service.Service.doSomething() throws my.module.shared.exception.MyCheckedException' threw an unexpected exception: my.module.shared.exception.AuthzRuntimeException: some authz message
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:389)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:579)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:208)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
Caused by: my.module.shared.exception.AuthzRuntimeException: some authz message
at my.module.shared.Authz.doSomeCheck(Authz.java:101)
at my.module.server.ServiceImpl.doSomething(ServiceImpl.java:283)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:561)
... 22 more
[ERROR] 500 - POST /module/userService (127.0.0.1) 57 bytes
Request headers
Host: 127.0.0.1:8888
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1:8888/foo.html?gwt.codesvr=127.0.0.1:9997
Cookie: worknet=7k8g41ulbl674dp865t180tji5
Connection: keep-alive
Cache-Control: no-cache
X-GWT-Permutation: HostedMode
X-GWT-Module-Base: http://127.0.0.1:8888/module/
Content-Type: text/x-gwt-rpc; charset=utf-8
Content-Length: 1076
Pragma: no-cache
Response headers
Content-Type: text/plain
(RequestCallbackAdapter.java:209) 2013-10-18 13:16:56,966 [WARN ] Fail ""
com.google.gwt.user.client.rpc.StatusCodeException: 500 The call failed on the server; see server log for details
at com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter.onResponseReceived(RequestCallbackAdapter.java:209)
at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:258)
at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:412)
at sun.reflect.GeneratedMethodAccessor40.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:338)
at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:219)
at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:571)
at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:279)
at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:242)
at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
at java.lang.Thread.run(Unknown Source)
GWT can only handle unchecked exceptions(which means sent from server to client) which are not serialized that extends from RuntimeException. I don't know what AlreadyActivatedError is. If it is not RuntimeException it can't be sent to the client(browser)
Maybe also note that if your specific Exception does not have a standard constructor, the generic 500 error message will also be displayed because it is not possible to deserialize the exception. Sadly, the gwt compiler and dev-mode plugin will not always point this problem out explicitly.. (that's how i got here anyway)
So, in combination with what vinnyjames said (the exception must be Serializable and be defined in the (RPC) service's interface), i found that processing exceptions in gwt client code is not too complicated.