javax.mail.NoSuchProviderException: smtp occurs when class is loaded from a custom class loader - classloader

I am working on a Java EE application with GlassFish as the application server. I have developed a pluggable addon for sending out emails(I have named it EmailProvider). For this, I am using late binding to load the EmailProvider jar at runtime. I have a custom URLClassLoader which loads the EmailProvider class file. The email provider has the JavaMail API to send out email. Here is the code snippet. This code works perfectly if I include the EmailProvider class in my Java EE application but throws an exception at
Transport transport = session.getTransport("smtp");
saying "javax.mail.NoSuchProviderException: smtp"i f I load the class at runtime using the customClassLoader. I know that this is classloading issue. I am also loading the javax.mail.jar through the customloader. I think the problem is same classes(javax.mail.jar) are being loaded from two different classloaders. If I omit javax.mail.jar then I get ClassNotFoundException for the javax.mail classes
Class EmailProvider{
try {
Properties props = new Properties();
props.put("mail.smtp.host", "IP ADDRESS");
props.put("mail.smtp.starttls.enable", "false");
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.class", "com.sun.mail.smtp.SMTPTransport");
Session session = Session.getInstance(props, null);
session.setDebug(false);
Provider provider = session.getProvider("smtp");
javax.mail.Message message = new MimeMessage(session);
InternetAddress addressFrom = new InternetAddress("name#some.com");
message.setFrom(addressFrom);
InternetAddress[] addressTo = new InternetAddress[1];
addressTo[0] = new InternetAddress("somenamea#gmail.com");
//msg.setRecipients(javax.mail.Message.RecipientType.TO, addressTo);
message.setSubject("Hello");
message.setContent("testing..", "text/plain");
session.setProvider(provider);
Transport transport = session.getTransport("smtp");
transport.connect("IP ADDRESS", "domain\\username", "password");
transport.sendMessage(message, addressTo);
} catch (Exception ex) {
Logger.getLogger(SendEmail.class.getName()).log(Level.SEVERE, null, ex);
} }

First, there's nothing named "JEE". The correct name is "Java EE".
The problem is that JavaMail can't find the configuration file in the javax.mail.jar file. It uses the thread's context class loader's getResource() method to find it. Assuming you've set up your custom class loader so that your application class loader is the parent class loader, you can set the thread's context class loader to your custom class loader.

Related

Could not find definition for webservice at wildfly 9

I wrote a webservice and the building Maven is all ok, but the deployment on wildfly 9 receives error:
Could not find definition for service {http://ws.sieciowyandroid.rogal.com/soap/Map}MapService.
all log server: here
wsdl is: here
and schema: here
and my code:
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
#WebService(name = "MapWebServiceEJB", targetNamespace = "http://ws.sieciowyandroid.rogal.com/soap/Map",
serviceName = "MapService", portName = "MapPort", wsdlLocation = "wsdl/api.wsdl")
public class MapWebService implements MapPort {
#Override
public GetThumbnailResp getThumbnail(#WebParam(partName = "in0", name = "GetThumbnailReq", targetNamespace = "http://ws.sieciowyandroid.rogal.com/soap/GetThumbnail") GetThumbnailReq in0) {
GetThumbnailResp response = new GetThumbnailResp();
try {
response.setResult("czesc "+ in0.getName());
} catch (Exception e) {
response.setResult("ERROR");
}
return response;
}
}
I did not notice a fault that could cause this exception.
I will be grateful for your help
This may or may not be related, but if you are using Maven to package the dependencies, then you may be stripping out the schema file mappings. I had a similar problem with Spring Framework and the answer posted here solve my problem. You can likely replace the spring references with the appropriate resources for your issue.
Idea to avoid that spring.handlers/spring.schemas get overwritten when merging multiple spring dependencies in a single jar

simple azure web service, http404 error on publish when adding /dowork to URL

I am trying my first web app service using Azure services. I've created it in VS, and it works locally. All it does it return a string that says "hello user" is JSON.
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1
{
// To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json)
// To create an operation that returns XML,
// add [WebGet(ResponseFormat=WebMessageFormat.Xml)],
// and include the following line in the operation body:
// WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
[OperationContract]
[WebGet(UriTemplate = "/DoWork")]
public string DoWork()
{
// Add your operation implementation here
return "hello user";
}
// Add more operations here and mark them with [OperationContract]
}
}
Problem is when I publish it, says successful. I can see it running on portal.
When I goto published site I get the standard THIS WEB APP HAS BEEN SUCCESSFULLY CREATED, but... when I add the /DoWork to the URL I get HTTP error 404.
I know I must be missing something simple...
any ideas?
you're missing the name of the service. In your case would be something like:
http://engineappservicev001.azurewebsites.net/something.svc/dowork
More info in here:
http://www.codeproject.com/Articles/571813/A-Beginners-Tutorial-on-Creating-WCF-REST-Services

How can you call a URL without opening a browser in C/Side?

We are using C/Side on one server to try to call a URL to a PHP script on another server without opening a browser window. We want the script to run as a background process. So far, everything we've tried opens a browser. Any suggestions?
I used HttpClient to do this. But it's not that straight forward in Nav, since you cannot call an asynchronous method and assign its return value to a variable. So I created a wrapper class in c#.
public class NavHttpClient
{
private HttpResponseMessage responseMsg;
public HttpResponseMessage ResponseMsg
{
get { return responseMsg; }
}
public async Task GetAsync(string requestUri)
{
HttpClient client = new HttpClient();
responseMsg = await client.GetAsync(requestUri);
}
}
Then I exported this class in a class library. Now I can use it Nav this way:
NavWebClient : DotNet NavWebClient.NavHttpClient.'NavWebClient, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
NavWebClient := NavWebClient.NavHttpClient;
NavWebClient.GetAsync('http://localhost').Wait;
IF NavWebClient.ResponseMsg.IsSuccessStatusCode THEN
...
Is this solution suits your needs? Inside there is link to codeunit for Nav 2013 that allows to work with web services in Nav style.

calling web service from login module n websphere

I have a websphere login module which calls a web service to get some information while authenticating. There is a different web service URL for different environments. Can anyone suggest the best way of deploying this so I dont have to redeploy the code between environments.
I have added the wsdl's to the META-INF folder in my deployed jar file. And set custom properties for the login module so I can determine which wsdl file to get.
However when I search for the wsdl it does not correctly load it as it throws a null pointer after intialisation.
[6/26/14 15:23:48:786 BST] 00000048 SystemOut O Debug: com.xxx.login.module.xxxCustomLoginModule
[6/26/14 15:23:48:786 BST] 00000048 SystemOut O got wsdl Url file:/usr/websphere7/ndb70SU3_B
117/lib/ext/xxxCustomLoginModule.jar!/META-INF/wsdl/my-pre.wsdl
the code I use to load it is the same as in the geenrated files
MYWS adamStub = null;
debugOut("WebserviceUrl = " +this.options.get("webServiceWsdlLocation"));
if(this.options.get("webServiceWsdlLocation") != null) {
URL wsdlUrl = getWsdlUrl();
debugOut("got wsdl Url " + wsdlUrl.getPath());
new MYWS (wsdlUrl, new QName(QNAME_WEBSERVICES, IADAM_L));
} else {
adamStub = new MYWS ();
}
and the get wsdl method
private URL getWsdlUrl() {
URL wsdlUrl = null;
try {
wsdlUrl = adam.xxxxxxx.class.getResource(
(String)this.options.get("webServiceWsdlLocation"));
if(wsdlUrl == null)
throw new MalformedURLException((String)this.options.get("webServiceWsdlLocation")+
" does not exist in the module.");
} catch(MalformedURLException e) {
e.printStackTrace();
}
return wsdlUrl;
}
I thought that this would have been the best way to do it for different environments but it cant seem to load the wsdl correctly. The get wsdl code is taken directly from the generated class and the line below works fine
adamStub = new MYWS ();
All suggestions are appreciated. I dont want to regenerate the client for each environment or from my build.
UPDATE:
Made a proper schoolboy error here forgot to do the assignment
new MYWS (wsdlUrl, new QName(QNAME_WEBSERVICES, IADAM_L));

JBoss EAP 5.1 Server not using Windows Network Setting

I'm trying to call a web service from my application. My system is protected with a Firewall and I'm using a Proxy to access any external URL/internet access. The application is running on JBoss EAP 5.1 server. The application fails to write to the service URL with IO Exception: 'Could not transmit message'.
However, when I'm trying to access the service URL with IE/Firefox, it's opening. Although the XML response I'm receiving from Browser states a generic error - 'invalid request parameters...', which is quite obvious. Because I'm not sending a proper request XML from Browser.
I'm really confused with this disparity. I used to believe that JBoss will pick up standard windows network settings, but in my case it is not.
My code is as follows:
String strUrl = "http://theurlgoeshere";
String requestXml = "<request></request>";
String wsResponse="";
SOAPConnection conn = null;
try {
MessageFactory msgFac = MessageFactory.newInstance();
MimeHeaders mh = new MimeHeaders();
mh.setHeader("Content-Type", "text/xml; charset=UTF-8");
log.info("Request Xml:" + requestXml );
InputStream is = new ByteArrayInputStream(requestXml.getBytes("UTF-8"));
SOAPMessage reqMsg = msgFac.createMessage(mh, is);
SOAPConnectionFactory conFac = SOAPConnectionFactory.newInstance();
conn = conFac.createConnection();
SOAPMessage repMsg = conn.call(reqMsg, strUrl);
ByteArrayOutputStream out = new ByteArrayOutputStream();
repMsg.writeTo(out);
wsResponse = new String(out.toByteArray());
}
catch (Exception e) {
e.printStackTrace();
}
Got it sorted few days back. Basically I am using HttpURLConnection now to add proxy setting in the java code itself while making the Webservice call. Just closing this question, since my query is solved.
Will update the new code, if anyone needs.