JavaMail
1 posts in topic
Flat View  Flat View
TOPIC ACTIONS:
 

Posted By:   Anonymous
Posted On:   Tuesday, November 5, 2002 04:34 AM

Hi! Whem I use the API JavaMail, I get to send a mail to ONE person, but when I try to send to ALL persons, to appear: java.lang.NullPointerException. Why? The code is below: <%! String mailServer = "192.168.1.3"; String subject = "Adetec News"; String from = "adetec@adetec.org.br"; String body = "NEWS NEWS NEWS NEWS"; %> try { Class.forName("oracle.jdbc.driver.OracleDriver"); Connection myConn = DriverManager.getConnection("jdbc:oracle:thin:@xxxxxxxxxx","xxxxxxx","xxxxxxxxxx"); Statement stmt = myConn.createStatement();    More>>

Hi! Whem I use the API JavaMail, I get to send a mail to ONE person, but when I try to send to ALL persons, to appear: java.lang.NullPointerException. Why? The code is below:



<%!

String mailServer = "192.168.1.3";

String subject = "Adetec News";

String from = "adetec@adetec.org.br";

String body = "NEWS NEWS NEWS NEWS";

%>




try {

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection myConn = DriverManager.getConnection("jdbc:oracle:thin:@xxxxxxxxxx","xxxxxxx","xxxxxxxxxx");

Statement stmt = myConn.createStatement();

ResultSet rs = stmt.executeQuery("select nome,nomeFant,email from TbPessoa order by nome");

if (rs != null) {

while(rs.next()){

if (rs.getString("NomeFant") == null){

String[] to = {rs.getString("email")};

System.out.println("Para xxxxxxxxxxxxxxxxxxxxxxxxxxx " + to);

sendEmail(mailServer, subject, to, from, body);

}

}

}

%>

Sucesso no envio do Adetec News.



<%

}

catch (AddressException e) {

%>

Endereço de e-mail inválido



<%

}

catch (MessagingException e) {

%>

Não foi possível enviar o e-mail



<%

}

%>







<%!

public void sendEmail (String mailServer, String subject,
String to[], String from, String messageText)

throws AddressException, MessagingException {

// Create session

Properties mailProps = new Properties();

mailProps.put("mail.smtp.host", mailServer);

Session mailSession = Session.getDefaultInstance(mailProps, null);

// Construct addresses

int toCount = to.length;

InternetAddress[] toAddrs = new InternetAddress[toCount];

for (int i = 0; i < toCount; ++i) {

toAddrs[i] = new InternetAddress(to[i]);

}

InternetAddress fromAddr = new InternetAddress(from);

// Create and initialize message

Message message = new MimeMessage(mailSession);

message.setFrom(fromAddr);

message.setRecipients(Message.RecipientType.TO, toAddrs);

message.setSubject(subject);

message.setContent(messageText.toString(), "text/plain");

// Send message

Transport.send(message);

}

%>





HELP !!!    <<Less

Re: JavaMail

Posted By:   michael_dean  
Posted On:   Tuesday, November 5, 2002 09:00 PM

Since you didn't include the stack trace and the "Root Cause" of the exception in your posting, I had to read the code extremely carefully to pinpoint the error (i.e. there are 70 lines--any of which could contain the problem--and I wasn't given any information narrowing it down). Therefore, I saw (and mention) several "little problems" (that won't cause errors, but should be changed). I hope you don't mind... :) If you just want the quick answer, it's at the bottom (but, IMHO, there's some good information in the
long answer).



First, I'll assume that the missing <% above the try block is not actually missing in your code (only in the post). Otherwise, it would not have compiled, so it wouldn't have worked when sending to a single recipient.



Second, there is no need for the conditional if (rs != null) since the executeQuery(String) method is guaranteed never to return null. I'm sure you added this to try to track down the NullPointerException, but now you can take it back out. :)



Third, your "diagnostic output" (System.out.println("Para xxxxxxxxxxxxxxxxxxxxxxxxxxx " + to);) will print out the toString() of an array object--which will look something like [Ljava.lang.String;@16f0472--which is probably not what you want.



Fourth, there's no reason to do a messageText.toString() in sendEmail(...)because messageText is a String (look at the method signature).



Fifth, there's a logic error in the while loop you use to process your ResultSet. You create a brand new array of a single String for each record returned by the query that contains a NULL value for the database column NomeFant (i.e. rs.getString("NomeFant") == null). Since this code and the sendEmail(...) method call are both inside the loop, you are calling sendEmail(...) multiple times (each time sending an e-mail to a single recipient). Although you can do this, it will be significantly more overhead than calling the method once (and, therefore, sending an e-mail only once) with an array of multiple recipients. However, if you want to continue making multiple calls, you could improve performance (slightly) by using the setRecipients(Message.RecipientType, String) method instead of the setRecipients(Message.RecipientType, String[]) method.



So, how can I create an array when I don't know how many results I'll have?
Well, you can take several approaches. First, you could use SQL to find out
the COUNT and use that value to instantiate the array. The
problem with this approach is that the database could change between executing
the two queries (so I recommend against this approach). Second, you could use collection classes (like href="http://java.sun.com/j2se/1.4.1/docs/api/java/util/ArrayList.html">java.util.ArrayList
to hold the values pulled from the ResultSet. From here, you
could then convert the ArrayList to an array of
Strings (lots of unnecessary overhead). Or, you could change
your sendEmail method to accept a reference of type href="http://java.sun.com/j2se/1.4.1/docs/api/java/util/List.html">java.util.List, pass it the reference to the ArrayList, and use the addRecipients(...) method instead of setRecipients(...). I highly recommend this approach.



Now, on to the root of the problem. Most likely, you are getting a null value from the database for the email column of one of your records. The InternetAddress(String) constructor method will throw a NullPointerException if the String reference passed to it is null. So, you might ask, why doesn't the documentation list that exception? Well, according to javadoc documentation standards, runtime exceptions (like NullPointerException) should never be listed in the "Throws" section of the javadoc. (Sun did this right. :) Instead, in a case like this--where the runtime exception could occur as a result of a bad parameter value---the documentation (method documentation or "Parameters" section) should specifically mention the possibility. (Sun forgot to do this.)



How can you tell that you'll get a NullPointerException instead of an AddressException? Run this program:




import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;

public class Test {
public static void main(String[] args) {
try {
String test = null;
InternetAddress address = new InternetAddress(test);
System.out.println(address);
} catch (MessagingException e) {
System.err.println(e);
e.printStackTrace();
}
}
}
About | Sitemap | Contact