JavaMail SocketException: разрешение отклонено: подключение

У меня проблема с программированием JavaMail в Netbeans. Когда я запускаю приведенный ниже код в среде IDE, электронное письмо отправляется, как и предполагалось. Но когда я выполняю очистку и сборку и пытаюсь выполнить то же действие из исполняемого файла JAR, я получаю от отладчика следующую информацию:

DEBUG: JavaMail version 1.5.2
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.gmail.com, 587; timeout -1;
  nested exception is:
    java.net.SocketException: Permission denied: connect

Я безуспешно пытался собрать как JDK1.8, так и JDK1.7. Многие сайты (например, пример) предлагают решить проблему IPv6 с некоторыми вариантами следующего в папке конфигурации netbeans: -Djava .net.preferIPv4Stack=true. Я также поместил это в параметры виртуальной машины, и, как вы можете видеть ниже, я также попытался реализовать это в своем коде. Другие попытки исправления, которые все еще остаются в силе, - это установка свойства socketFactor.class на javax.net.ssl.SSLSocketFactory, установка TrustAllHosts MailSSLSocketFactory на true и использование метода sendMessage() в экземпляре класса Transport для отправки электронной почты. Все не удалось.

Я попытался подключиться к gmail по телнету через порт 587 и строку cmd, и соединение было успешно установлено.

Я сам большой поклонник отладки вещей, но прошло уже больше недели, и, хотя многие люди, кажется, разделяют проблему SocketException, ни одно из решений не было эффективным.

Я открыт для решения этой проблемы или, честно говоря, любых альтернативных способов отправки электронных писем с помощью Java. Чтение электронной почты не важно для этого кода. Наиболее полезными являются фрагменты кода, а не просто описания, поэтому я могу добавить их в свой код для запуска. Заранее спасибо!

Соответствующий сегмент кода (работает в Windows 7):

    static void sendEmail(String toAddress, String subject, String body) throws NoSuchProviderException, MessagingException, GeneralSecurityException {
        try {
            System.setProperty("java.net.preferIPv4Stack", "true");
            String host = "smtp.gmail.com";
            String username = "[email protected]";
            String password = "password";
            Properties props = new Properties();
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.starttls.enable", "true");
            props.put("mail.smtp.host", host);
            props.put("mail.smtp.port", "587");
            props.put("mail.debug", "true");
            props.put("mail.smtp.debug", "true");
            props.put("mail.smtp.password", password);
            props.put("mail.smtp.user", "sampleuser");
            props.put("mail.smtp.socketFactory.class",
                    "javax.net.ssl.SSLSocketFactory");
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);

            Session session = Session.getInstance(props);
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(username));
            message.setRecipients(Message.RecipientType.TO,
                    InternetAddress.parse(toAddress));
            message.setSubject(subject);
            message.setText(body);
            Transport t = session.getTransport("smtp");
            try {
                t.connect(host, username, password);
                t.sendMessage(message, message.getAllRecipients());
            }catch(Exception e){
                System.out.println(e);
            } finally {
                t.close();
            }
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }

person Zach Sperry    schedule 29.07.2014    source источник


Ответы (2)


Возможно, это свойство необходимо установить при запуске JVM? Попробуйте запустить с "java -Djava.net.preferIPv4Stack=true -jar ...."

Возможно, у вас есть какой-то антивирус или брандмауэр, который препятствует подключению «java», но разрешает подключение «telnet»? Попробуйте временно отключить любой антивирус или брандмауэр для проверки.

person Bill Shannon    schedule 29.07.2014
comment
Установка свойства раньше времени сработала! Я не знал такого синтаксиса, спасибо. Так что я должен запускать его из командной строки каждый раз? Я надеялся упаковать это в .jar, чтобы раздать своим коллегам... - person Zach Sperry; 30.07.2014
comment
Обновление: просто для удовольствия я перезапустил его из командной строки как java -Djava.net.preferIPv4Stack=false -jar .... и это все равно сработало (установите для свойства значение false). Кажется, проблема возникает только тогда, когда я открываю свой исполняемый файл двойным щелчком. - person Zach Sperry; 30.07.2014
comment
Интересно. Это все еще может быть связано с вашим антивирусом или брандмауэром, где он знает, что можно разрешить команду java, но не знает, разрешить ли ваш файл jar. - person Bill Shannon; 30.07.2014
comment
Это имело бы смысл. К сожалению, я не думаю, что имею право голоса по поводу антивируса или брандмауэра. Большая компания, большой ИТ-отдел. Я попытался упаковать его в файл .cmd, который решает проблему. Единственная проблема в том, что я не хочу, чтобы мои пользователи видели командное окно. Есть ли способ запустить его из файла .cmd и скрыть командное окно? - person Zach Sperry; 30.07.2014
comment
Мое окончательное решение, воспользовавшись предложением Билла, состояло в том, чтобы создать файл .txt со следующим кодом: set path=C:\Program Files (x86)\Java\jre7\bin [NEW LINE] start /min java -Djava.net.preferIPv4Stack=true -jar "Path\to\jar\file.jar" и сохранить файл как файл .cmd. Это открывает файл и запускает свернутую, но все еще полезную командную строку, пока работает .jar. - person Zach Sperry; 30.07.2014

Теперь Gmail поставляется с отключенной по умолчанию функцией входа и защиты. Включите его для своей учетной записи, и он должен работать нормально.

https://myaccount.google.com/security

person Ajay Menon    schedule 18.07.2015