I want to program a "Contact Us" form in my desktop application (Swing in Netbeans), just like what we find in some websites.
The problem that I faced is the smtp server name. Actually, I want that the user could send me a message without giving his address mail and without requiring that he connects to his account either.
Here a screen shot:
And this is my Submit button action:
#Override
public void actionPerformed(ActionEvent e) {
boolean isSent = true;
try {
//Properties properties = new Properties();
Properties properties = System.getProperties();
// properties.setProperty("mail.smtp.submitter", contactUs.getMailField().getText());
//properties.setProperty("mail.smtp.auth", "false");
properties.setProperty("mail.smtp.host", "localhost");
//properties.put("mail.smtp.user", txtfrom.getText());
//properties.put("mail.smtp.port", txtPort.getText());
//properties.put("mail.smtp.socketFactory.port", txtPort.getText());
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
properties.put("mail.smtp.socketFactory.fallback", "false");
//Authenticator mailAuthenticator = new MailAuthenticator();
Session mailSession = Session.getDefaultInstance(properties);
Message message = new MimeMessage(mailSession);
InternetAddress fromAddress = new InternetAddress(contactUs.getMailField().getText());
InternetAddress toAddress = new InternetAddress("mancha#gmail.com");
message.setFrom(fromAddress);
message.setRecipient(Message.RecipientType.TO, toAddress);
message.setSubject(contactUs.getSubjectField().getText());
message.setText(contactUs.getMsgField().getText());
Transport.send(message);
} catch (Exception ex) {
contactUs.getErrorMsg().setText("ERROR:" + ex.getMessage());
isSent = false;
}
if (isSent == true) {
contactUs.getSubmitBtn().setEnabled(false);
contactUs.getErrorMsg().setText("Your e-mail has been sent.");
}
}
Of course I google and I found that simple example which causes always problem of connection to smtp server.
First of all, make sure that your smtp server listens on port 25.
you can check it via telnet.
telnet localhost 25
if you do not have any, install a smtp service to your system.
if you have, check your smtp services security settings to connect it
Firstly check that your mail server is up and running by running
telnet localhost 25
Secondly you don't want to set the fromAddress as the users 'prescribed' email as that would require the account exists on your local mail server (As often people contacting you wouldn't already be on your system). Instead, temporarily hard code the fromAddress to an email address you know exists on your mail server and just append the users email address to the email.
An example of what you might want to do
final String FROM_EMAIL_ADDRESS = yourexistingemail#mailserver.com;
InternetAddress fromAddress = new InternetAddress(FROM_EMAIL_ADDRESS);
message.setText(contactUs.getMsgField().getText(), "\nFrom: " + contactUs.getMailField().getText());
Related
I'm trying to setup a program which can automatically send e-mails. However, the first step doesn't even work for me and it gives this error:
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: 127.0.0.1, 25; timeout -1;
nested exception is:
java.net.ConnectException: Connection refused: connect
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2209)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740)
at javax.mail.Service.connect(Service.java:366)
at javax.mail.Service.connect(Service.java:246)
at javax.mail.Service.connect(Service.java:195)
at javax.mail.Transport.send0(Transport.java:254)
at javax.mail.Transport.send(Transport.java:124)
at server.main(server.java:46)
Caused by: java.net.ConnectException: Connection refused: connect
at java.base/java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.base/java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:400)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:243)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:225)
at java.base/java.net.PlainSocketImpl.connect(PlainSocketImpl.java:148)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:402)
at java.base/java.net.Socket.connect(Socket.java:591)
at java.base/java.net.Socket.connect(Socket.java:540)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:353)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:239)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175)
... 7 more
This is the code:
// File Name SendEmail.java
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
public class server {
public static void main(String [] args) {
// Recipient's email ID needs to be mentioned.
String to = "my other email properly written";
// Sender's email ID needs to be mentioned
String from = "my email properly written";
// Assuming you are sending email from localhost
String host = "127.0.0.1";
// Get system properties
Properties properties = System.getProperties();
// Setup mail server
properties.setProperty("mail.smtp.host", host);
// 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(from));
// Set To: header field of the header.
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
// Set Subject: header field
message.setSubject("This is the Subject Line!");
// Now set the actual message
message.setText("This is actual message");
// Send message
Transport.send(message);
System.out.println("Sent message successfully....");
} catch (MessagingException mex) {
mex.printStackTrace();
}
}
}
Does anyone have any idea why this happens and how to solve this? My e-mail is actually open etc. And because it's localhost I have no idea why it wouldn't work.
Access to a SMTP server would require the smtp host port and the security settings if applicable.
Properties props = new java.util.Properties();
props.put("mail.smtp.host", "hostname") #
props.put("mail.smtp.port", "portnumber") #25
props.put("mail.smtp.starttls.enable", "boolean value true or false")
props.put("mail.smtp.auth", "boolean value true or false")
Usually a session need to be created (a Java mail session using the username and password and the properties), that is missing in the code above. For demonstration purpose,
Session session = javax.mail.Session.getInstance( props,
new javax.mail.Authenticator() {
protected javax.mail.PasswordAuthentication getPasswordAuthentication() {
return new javax.mail.PasswordAuthentication("username", "password"); //username and password
}
});
I am working with JavaMail for my plugin, within this plugin I am trying to send an email but my issue lies around the client. The client can't handle the plugin connecting to the email server and sending an email it either crashes the entire server or the client gets kicked out. My fix for this was instead of constantly connecting to the email server and sending an email why not simply keep one connection open when the plugin starts and grab that connection when I am wanting to send an email hopefully this will help in allowing the client and server to stay stable without any crashes. If anyone can help me I am just curious on how I can go about keeping a a single connection open and grabbing it when it is needed and then closing it when the plugin gets disabled.
What I have tried:
private Session session;
public void connect() {
String provider = plugin.getConfig().getString("EmailProvider");
String email = plugin.getConfig().getString("Email");
String password = plugin.getConfig().getString("Password");
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", provider);
props.put("mail.smtp.port", "25");
session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(email, password);
}
});
}
private boolean checkSession() {
try {
if (session != null) {
return true;
} else {
return false;
}
}
return false;
}
public void sendEmail(String to, String from, String subject, String text) {
if (!checkSession()) {
connect();
System.out.println("connecting");
}
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(subject);
message.setText(text);
Transport.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
The simple answer is, you can't.
There's no way to force a connection to remain open. Connections can be closed for all sorts of reasons and your program needs to be prepared for that.
You can, however, cache an open connection and reuse it as long as it's still connected. But without knowing what your plugin plugs in to, it's hard to describe the best strategy for that.
Note also that mail servers really don't want you to keep a connection open if you're not using it, which is why they'll close it out from under you if you leave it open but idle for too long. And artificially keeping the connection active won't win you any points with the mail server either.
If your mail server crashes when you connect to it, it's probably time to get a new mail server.
I'm writing a small Java app using JavaMail that sends the user an automated email. They can choose between (for now) two ports: 25 and 587. The port can be selected via a radio button on the GUI.
I added a test button to allow the user to test the email settings (including port). However, for some reason, once the user tries to send a test email, the port can't be changed. Javamail will always use the port of the original test email.
Example: User tries to send an email on port 25 and JavaMail says it can not connect on port 25 (for example, the SMTP host uses another port). User clicks port 587, and tries to send a new email. JavaMail throws an error saying it can not connect on port 25, again.
I'm kind of stumped as to why. Every time a new test email is sent an entirely new SendMailUsingAuthentication object is created. Within that class the properties are always reset to the proper port. Whenever I debug, as far as I can see, all variables are correct and associated with the correct port. Is there something going on inside of Transport that I'm missing?
In the front end GUI:
private void testButtonActionPerformed(java.awt.event.ActionEvent evt) {
int port = port25RadioButton.isSelected() ? PORT_25 : PORT_587;
notifier = new SendMailUsingAuthentication(hostNameTextField.getText(),
userTextField.getText(), getPassword(), emailTextField.getText().split(","),port);
Thread wait = new Thread(new Runnable() {
public void run() {
try {
changeStatusText("Sending test email...");
notifier.postTestMail();
changeStatusText("Test email sent.");
} catch (AddressException ex) {
changeStatusText("Error. Invalid email address name.");
} catch (MessagingException ex) {
changeStatusText("SMTP host connection refused.");
System.err.println(ex.getMessage());
} catch (Exception ex) {
System.err.println(ex);
}
}
});
wait.start();
}
In the email sender class:
public void postTestMail() throws MessagingException, AddressException{
String[] testReciever = new String[1];
testReciever[0] = emailList[0];
postMail(testReciever, "Test email.", "Your email settings are successfully set up.", emailFromAddress);
}
private void postMail(String recipients[], String subject,
String message, String from) throws MessagingException, AddressException {
//Set the host smtp address
Properties props = new Properties();
props.put("mail.smtp.port", smtpPort);
props.put("mail.smtp.host", smtpHostName);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", true);
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getDefaultInstance(props, auth);
session.setDebug(false);
// create a message
Message msg = new MimeMessage(session);
// set the from and to address
InternetAddress addressFrom = new InternetAddress(from);
msg.setFrom(addressFrom);
InternetAddress[] addressTo = new InternetAddress[recipients.length];
for (int i = 0; i < recipients.length; i++) {
addressTo[i] = new InternetAddress(recipients[i]);
}
msg.setRecipients(Message.RecipientType.TO, addressTo);
// Setting the Subject and Content Type
msg.setSubject(subject);
msg.setContent(message, "text/plain");
Transport.send(msg);
}
This happens because you're using getDefaultInstance() which says:
Get the default Session object. If a default has not yet been setup, a new Session object is created and installed as the default.
And that the Properties argument is "used only if a new Session object is created."
So the first time you invoke getDefaultInstance it uses your specified port. After that, the Session has already been created, and subsequent calls to getDefaultInstance will return that same session, and ignore the changed properties.
Try using Session.getInstance() instead of getDefaultInstance(), which creates a new Session each time, using the supplied properties.
It pays to read the javadocs very carefully.
Tip for anyone else still having issues, we were using Session.getInstance and the port was still defaulting to 25.
Turns out, we were setting the prop value as a Long when it needs to be a String
It didn't error, warn or log, just defaulted to 25.
I think "Transport.send(msg)" wont be taking into account the connection details that you are providing in your properties. It will use its connection that is defined by default.
The java doc says
"Note that send is a static method that creates and manages its own connection. **Any connection associated with any Transport instance used to invoke this method is ignored and not used. This method should only be invoked using the form Transport.send(msg);, and should never be invoked using an instance variable. "**
Instead, I have tried with Transport.connect(smtphost,smtpport,user,password) and it works pretty well.
Plz compare two methods of Session class: Session.getDefaultInstance(Properties, Authenticator) and Session.getInstance(Properties, Authenticator)
I am looking for a Java class that will allow me to send emails without the need for SMTP. Like the PHP mail() class that uses sendmail.
Any suggestions?
Many Thanks
James
Before Using this Program, you need to have Javasoft's JavaMail class files which can be downloaded from here http://www.javasoft.com/products/javamail/index.html
You will also need the JavaBeansTM Activation Framework extension or JAF (javax.activation). It is available at http://java.sun.com/beans/glasgow/jaf.html.
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
public void postMail( String recipients[ ], String subject, String message , String from) throws MessagingException
{
boolean debug = false;
//Set the host smtp address
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.jcom.net");
// create some properties and get the default Session
Session session = Session.getDefaultInstance(props, null);
session.setDebug(debug);
// create a message
Message msg = new MimeMessage(session);
// set the from and to address
InternetAddress addressFrom = new InternetAddress(from);
msg.setFrom(addressFrom);
InternetAddress[] addressTo = new InternetAddress[recipients.length];
for (int i = 0; i < recipients.length; i++)
{
addressTo[i] = new InternetAddress(recipients[i]);
}
msg.setRecipients(Message.RecipientType.TO, addressTo);
// Optional : You can also set your custom headers in the Email if you Want
msg.addHeader("MyHeaderName", "myHeaderValue");
// Setting the Subject and Content Type
msg.setSubject(subject);
msg.setContent(message, "text/plain");
Transport.send(msg);
}
I found it:
http://examples.oreilly.com/jenut/SendMail.java
Thanks all.
All mail senders will need an SMTP server to transfer their mail. The nice thing about PHP mail is that you don’t need to configure it (it use the sendmail binary directly, if sendmail is not installed, PHP mail will not work either).
If all you want is building a Java application that can send out e-mail without configuring an SMTP server for that, you could use a Java based SMTP server, for example:
Apache James
I need to send simple html-message with JavaMail. And when I tried to find some nice examples with explanations in the Internet, each next example made me more angry and angry.
All those silly examples contain copied and pasted Java code which differs only in comments and a nice disclaimer that first you should config your smtp and pop3 server.
I understand that nobody wants to make an advertise for some concrete products but configuring the server is imho the hardest part. So, can anyone give me some really useful information (without java code) about configuring concrete server (Kerio, for example, or any other one)?
What I have now is the next exception:
250 2.0.0 Reset state
javax.mail.SendFailedException: Invalid Addresses;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 Relaying to <mymail#mycompany.com> denied (authentication required)
UPD. Simple reformulation of all previous text is: imagine that you have Windows, jdk, and nothing else. And you want to make java program and run it on your machine. And this program should send "Hello world!" to your gmail account. List your steps.
UPD2. Here is the code:
Properties props = new Properties ();
props.setProperty ("mail.transport.protocol", "smtp");
props.setProperty ("mail.host", "smtp.gmail.com");
props.setProperty ("mail.user", "my_real_address_1#gmail.com");
props.setProperty ("mail.password", "password_from_email_above");
Session mailSession = Session.getDefaultInstance (props, null);
mailSession.setDebug (true);
Transport transport = mailSession.getTransport ();
MimeMessage message = new MimeMessage (mailSession);
message.setSubject ("HTML mail with images");
message.setFrom (new InternetAddress ("my_real_address_1#gmail.com"));
message.setContent ("<h1>Hello world</h1>", "text/html");
message.addRecipient (Message.RecipientType.TO,
new InternetAddress ("my_real_address_2#gmail.com"));
transport.connect ();
transport.sendMessage (message,
message.getRecipients (Message.RecipientType.TO));
And exception is:
RSET
250 2.1.5 Flushed 3sm23455365fge.10
com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. 3sm23455365fge.10
at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1829)
at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1368)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:886)
at com.teamdev.imgmail.MailSender.main(MailSender.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
...
If you're looking for a tutorial to configure an SMTP server, you shouldn't be looking for JavaMail. Simply look for a tutorial on your server of choice (Kerio, for example ... or Exim, SendMail, Apache James, Postfix) or ask on Serverfault. Any SMTP-compliant server will play nicely with JavaMail.
Alternatively, you may even use any "standard" mail provider's infrastructure. For example, I use a Google Apps account along with Google's SMTP infrastructure to send mail from our Java applications. Using a Gmail account is a good starting point anyway if you don't want to setup your own SMTP server in order to simply testdrive JavaMail.
As a last option, you might even lookup the MX Records for a domain and deliver your mails directly to the SMTP server of the recipient. There are some common gotchas to workaround tough.
As a last point, you'll have to look into how to avoid that your mails be filtered as spam - which is a huge topic itself. Here it helps to rely on standard providers that will deal with some of the issues you might encounter when hosting your own server.
Btw: Regarding the error message you posted: the SMTP server is denying relaying of messages. This is if your SMTP server (thinks that it) is running on example.com and you're sending as bob#example.net to alice#example.org, you're asking the SMTP server to act as a relay. This was common practice several years ago, until it was - you guessed it - abused by spammers. Since those days, postmasters are encouraged to deny relaying. You have two choices: authenticate before sending mail or send to accounts hosted at your server only (i.e. on example.com, e.g. alice#example.com).
Edit:
Here is some code to get you started with authenticationg (works with Gmail accounts but should do for your own server as well)
private Session createSmtpSession() {
final Properties props = new Properties();
props.setProperty("mail.smtp.host", "smtp.gmail.com");
props.setProperty("mail.smtp.auth", "true");
props.setProperty("mail.smtp.port", "" + 587);
props.setProperty("mail.smtp.starttls.enable", "true");
// props.setProperty("mail.debug", "true");
return Session.getDefaultInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("john.doe#gmail.com", "mypassword");
}
});
}
I can see part of your problem. It's adequately explained in the error message.
The SMTP server you are sending your mail to (i.e. one of the addresses you've configured in your JavaMail configuration) is refusing to forward mail to mymail#company.com. Looks like a configuration issue in your SMTP server. As sfussenegger indicated, it has nothing to do with javamail.
So you're not debugging on all fronts at the same time, it might be a good idea to try addressing your SMTP server from a known working SMTP client. Thunderbird would do fine, for example. If you can send mail through it from Thunderbird, there should be little problem from JavaMail.
Update:
The correct address for Google's SMTP server is: smtp.gmail.com . Is this the server you have configured in JavaMail? Can you show us the matching error message?
A working example combining the above answers, using activation-1.1.jar and mail-1.4.1.jar and the SMTP host is Gmail.
Replace user#gmail.com and user_pw in line return new PasswordAuthentication("user#gmail.com", "user_pw");
Also, you want to replace myRecipientAddress#gmail.com by the email address where you want to receive the email.
package com.test.sendEmail;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
public class sendEmailTest {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
sendEmailTest emailer = new sendEmailTest();
//the domains of these email addresses should be valid,
//or the example will fail:
emailer.sendEmail();
}
/**
* Send a single email.
*/
public void sendEmail(){
Session mailSession = createSmtpSession();
mailSession.setDebug (true);
try {
Transport transport = mailSession.getTransport ();
MimeMessage message = new MimeMessage (mailSession);
message.setSubject ("HTML mail with images");
message.setFrom (new InternetAddress ("myJavaEmailSender#gmail.com"));
message.setContent ("<h1>Hello world</h1>", "text/html");
message.addRecipient (Message.RecipientType.TO, new InternetAddress ("myRecipientAddress#gmail.com"));
transport.connect ();
transport.sendMessage (message, message.getRecipients (Message.RecipientType.TO));
}
catch (MessagingException e) {
System.err.println("Cannot Send email");
e.printStackTrace();
}
}
private Session createSmtpSession() {
final Properties props = new Properties();
props.setProperty ("mail.host", "smtp.gmail.com");
props.setProperty("mail.smtp.auth", "true");
props.setProperty("mail.smtp.port", "" + 587);
props.setProperty("mail.smtp.starttls.enable", "true");
props.setProperty ("mail.transport.protocol", "smtp");
// props.setProperty("mail.debug", "true");
return Session.getDefaultInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("user#gmail.com", "user_pw");
}
});
}
}
This should work:
import java.text.MessageFormat;
import java.util.List;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class Emailer {
public static void main(String[] args) {
String hostname = args[0];
final String userName = args[1];
final String passWord = args[2];
String toEmail = args[3];
String fromEmail = args[4];
String subject = args[5];
String body = "";
// add rest of args as one body text for convenience
for (int i = 6; i < args.length; i++) {
body += args[i] + " ";
}
Properties props = System.getProperties();
props.put("mail.smtp.host", hostname);
Session session = Session.getInstance(props, new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, passWord);
}
});
MimeMessage message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress(fromEmail));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
message.setSubject(subject);
message.setText(body);
Transport.send(message);
} catch (MessagingException e) {
System.out.println("Cannot send email " + e);
}
}
}
You need to put the JavaMail mail.jar on your classpath for the javax.mail dependencies.
I'm not sure if Google lets you send email like you want to. How about trying another email provider, like your ISP's?