본문 바로가기

[IT/Programming]/HTML related

Email by JAVA (자바 프로그램을 이용해 이메일 보내기, com.sun.mail:jakarta.mail:2.0.1 :: 2021-04-06 에 update 가 끝나있는 오래된 library 임.)

반응형
# Email by JAVA (자바 프로그램을 이용해 이메일 보내기, com.sun.mail:jakarta.mail:2.0.1 :: 2021-04-06 에 update 가 끝나있는 오래된 library 임.) 이메일 (Email) 을 프로그래밍적으로 보내고 싶은데 어떻게 해야할까? 개인적으로는 Recoeve.net 에 회원가입을 할 때, 계정 만들고 이메일 통해 인증/확인 하기 위한 용도로 이메일을 활용하려고 하는 중인데, 또 비밀번호를 잊어버렸다거나 했을때의 보완수단으로서 활용하려고... 이러려면 아무튼 프로그래밍적으로 이메일을 보낼 수 있어야 한다. 어떻게 하면 될까? ## TOC ## Gmail (지메일) by com.sun.mail:jakarta.mail:2.0.1 (2021-04-06)
Gmail 에서 JAVA 프로그래밍을 통한 이메일을 보내려면 계정설정에서 앱 비밀번호로 로그인 이 가능하도록 2단계 인증을 거쳐 16자리 새로운 암호를 할당받아야 한다.
Email Server 까지 만들기는 귀찮으니 많이들 사용하는 Gmail 계정을 JAVA 와 연결해서 메일을 보내는 법을 알아봅시다. 우선 를 다운 받거나 gradle 이나 maven dependency 에 추가시키자. ### build.gradle.kts 제 build.gradle.kts 파일은 다음과 같음. (Vert.x server 를 쓰기 때문에...) ```[.linenums.lang-kts] import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.gradle.api.tasks.testing.logging.TestLogEvent.* plugins { java application id("com.github.johnrengelman.shadow") version "8.1.1" } group = "net.recoeve" version = "1.0.0-SNAPSHOT" repositories { mavenCentral() } val vertxVersion = "4.5.1" val junitJupiterVersion = "5.9.1" val mainVerticleName = "recoeve.http.MainVerticle" val launcherClassName = "io.vertx.core.Launcher" val watchForChange = "src/**/*" val doOnChange = "${projectDir}/gradlew classes" application { mainClass.set(launcherClassName) } dependencies { implementation("io.netty:netty-all:4.1.104.Final") // https://mavenlibs.com/maven/dependency/mysql/mysql-connector-java implementation("mysql:mysql-connector-java:8.0.33") // https://mavenlibs.com/maven/dependency/com.mysql/mysql-connector-j implementation("com.mysql:mysql-connector-j:8.1.0") // https://mvnrepository.com/artifact/jakarta.mail/jakarta.mail-api implementation("com.sun.mail:jakarta.mail:2.0.1") implementation("org.jsoup:jsoup:1.17.1") // https://mvnrepository.com/artifact/io.vertx/vertx-core implementation("io.vertx:vertx-core:$vertxVersion") //Thanks for using https://jar-download.com implementation("io.micrometer:micrometer-registry-prometheus:1.12.1") // https://mvnrepository.com/artifact/io.vertx/vertx-micrometer-metrics implementation("io.vertx:vertx-micrometer-metrics:$vertxVersion") implementation(platform("io.vertx:vertx-stack-depchain:$vertxVersion")) implementation("io.vertx:vertx-web-client") implementation("io.vertx:vertx-web") implementation("io.vertx:vertx-web-openapi") implementation("io.vertx:vertx-mysql-client") implementation("io.vertx:vertx-http-service-factory") implementation("io.vertx:vertx-json-schema") implementation("io.vertx:vertx-web-api-contract") implementation("io.vertx:vertx-rx-java3") implementation("io.vertx:vertx-auth-oauth2:$vertxVersion") implementation("io.vertx:vertx-jdbc-client") implementation("io.vertx:vertx-config") implementation("io.vertx:vertx-rx-java2") implementation("io.vertx:vertx-rx-java") implementation("io.vertx:vertx-mail-client") implementation("io.vertx:vertx-auth-jdbc") testImplementation("io.vertx:vertx-junit5") testImplementation("org.junit.jupiter:junit-jupiter:$junitJupiterVersion") implementation("org.seleniumhq.selenium:selenium-java:4.17.0") // https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java } java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } tasks.withType<ShadowJar> { archiveClassifier.set("fat") manifest { attributes(mapOf("Main-Verticle" to mainVerticleName)) } mergeServiceFiles() } tasks.withType<Test> { useJUnitPlatform() testLogging { events = setOf(PASSED, SKIPPED, FAILED) } } tasks.withType<JavaExec> { args = listOf("run", mainVerticleName, "--redeploy=$watchForChange", "--launcher-class=$launcherClassName", "--on-redeploy=$doOnChange") } ```/ ```[.linenums] gradlew build gradlew run // 과 같은 명령어로 java 파일 전체를 compile 하고 dependencies 를 자동으로 다운받고 할 수 있음. ```/ ### JAVA code 그리고 아래와 같이 JAVA 코드를 작성하면 잘 돌아감. 해당 코드는 https://mailtrap.io/blog/jakarta-mail-tutorial/#Sending-HTML-email-in-Jakarta-Mail 에서 가져왔고, 제가 class 이름, 변수 등을 약간 수정함. ```[.scrollable.lang-java] package recoeve.http; import jakarta.mail.*; import jakarta.mail.internet.InternetAddress; import jakarta.mail.internet.MimeMessage; import java.util.Properties; public class Gmail { private static final String username = "recoeve"; private static final String amho = "***amho***"; // 구글계정에서 2단계 인증을 거쳐 받은 16자리 앱 암호입력. private static final Properties prop = new Properties(); static { prop.put("mail.smtp.host", "smtp.gmail.com"); prop.put("mail.smtp.port", "465"); prop.put("mail.smtp.auth", "true"); prop.put("mail.smtp.socketFactory.port", "465"); prop.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); } private static final Session session = Session.getInstance( prop, new jakarta.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, amho); } }); /** * Send email using Gmail SMTP server. * * @param recipientEmail TO recipient * @param ccEmail CC recipient. Can be empty if there is no CC recipient * @param title title of the message * @param message message to be sent * @throws MessagingException if the connection is dead or not in the connected * state or if the message is not a MimeMessage */ public static void send(String recipientEmail, String ccEmail, String title, String message) { try { Message msg = new MimeMessage(session); msg.setFrom(new InternetAddress("recoeve@gmail.com")); msg.setRecipients( Message.RecipientType.TO, InternetAddress.parse(recipientEmail)); msg.setSubject(title); msg.setContent(message, "text/html; charset=utf-8"); Transport.send(msg); } catch (MessagingException e) { e.printStackTrace(); } } public static void main(String... args) throws Exception { Gmail.send("kipid84@naver.com", "", "title", "<h1>HTML message.</h1>"); // 테스트. } } ```/ ### "Not provider of jakarta.mail.util.StreamProvider was found" Error handle 최근까지 업데이트 되고 있는 https://mvnrepository.com/artifact/jakarta.mail/jakarta.mail-api/2.1.3 를 dependency 에 넣고 실행시켰더니 "Not provider of jakarta.mail.util.StreamProvider was found" 에러가 발생했었음. 뭔가가 업데이트 되면서 code 를 좀 바꿔줘야 하는것도 같은데... 방법을 찾기가 너무 어려워서 그냥 downgrade 시킨 버전으로 해결 봤음.
최신 버전 사용법을 알고 계신 분은 댓글로 좀 알려주세요.
## Email Server 만들기 아예 Email Server 까지 돌리면서 JAVA 랑 연결해서 자동화 시키는 방법도 있는거 같긴한데... 귀찮;;; 방법은 알아서 찾아보시길. 시간날때 정리하겠음; (아예 안할지도ㅋ) ## 네이버 메일 by 자바 (Naver mail by JavaMail) :: 너무 오래된 문서라 지금은 도움이 안될듯. 우선 에서 javax.mail.jar file 을 다운받읍시다. 적당한 폴더에 넣어놓고, 이 폴더\javax.mail.jar 를 윈도우 변수(?) CLASSPATH 에 포함시킵시다. 아니면 java compile 하거나 실행시킬때, javac -classpath "folder path\javax.mail.jar;other classes", java -classpath "folder path\javax.mail.jar;other classes" 식으로 실행시키면 됨. 그리고 아래와 같이 JAVA 코드를 작성하면 잘 돌아감. 해당 코드는 에서 가져왔고, 제가 class 이름 등 약간 수정함. 아래와 같은 코드로 잘 동작했었는데, 최근에 뭔가 바뀐건지 AWS server 에서는 잘 동작을 안함. Error 잡는 중. 혹시 아시는 분 있으면 도와주세요~!
AWS 의 Outbound rule (아웃바운드 규칙) 을 잘 설정해줘야 했었음. SMTP port 가 587 을 기본적으로 이용하던데, 기존의 Outbound rule 에서는 1024 - 65XXX 까지 포트만 열어놨었어서 timeout 이 발생한 것인듯. 친구 구경렬의 도움으로 해!결! 땡큐~!
```[.scrollable.lang-java] package recoeve.http; import com.sun.mail.smtp.*; // import java.security.Security; // import java.util.Date; import java.util.Properties; import javax.mail.*; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; // For import: download javax.mail.jar file from Java.net - The Source for Java Technology Collaboration - JavaMail API // and include the filepath in classpath. // C:\Recoeve\classes\javax.mail.jar // API: Package com.sun.mail.smtp // https://javamail.java.net/nonav/docs/api/com/sun/mail/smtp/package-summary.html // https://developers.google.com/appengine/docs/java/mail/usingjavamail /** * https://stackoverflow.com/questions/3649014/send-email-using-java * asked Sep 6 '10 at 4:34 by Mohit Bansal * @author doraemon */ public class NaverMail{ public static void sendChangePwd(String id, String email, String token, String lang) throws AddressException, MessagingException { String title="Forgot password on Recoeve.net?"; if (lang.equals("ko")) { title="Recoeve.net 의 비밀번호를 잊어버리셨나요?"; } String url="https://"+Recoeve.HOST+"/account/changePwd?id="+id+"&email="+email+"&token="+token; String msg="<span style='line-height:1.6; font-family:'Malgun Gothic', '맑은 고딕', 나눔고딕, NanumGothic, Tahoma, Sans-serif; font-size:27px'>Within 10 minutes after you receive this email, please visit<br><a href='"+url+"&lang=en"+"'>"+url+"&lang=en"+"</a>.<br><br><br><br>이메일을 받으신 후 10분내로 다음 링크를 방문해주세요.<br><a href='"+url+"&lang=ko"+"'>"+url+"&lang=ko"+"</a></span>"; NaverMail.send(email, "", title, msg); } public static void sendVeriKey(String email, String id, String veriKey) throws AddressException, MessagingException { String title="Verify your account on Recoeve.net"; String url="https://"+Recoeve.HOST+"/account/verify/"+id+"/"+veriKey; String msg="<span style='line-height:1.6; font-family:'Malgun Gothic', '맑은 고딕', 나눔고딕, NanumGothic, Tahoma, Sans-serif; font-size:27px'>Thanks for your registration on <a href='https://recoeve.net/'>Recoeve.net</a>.<br><br>Please log in <a href='https://recoeve.net/'>Recoeve.net</a> first, and then click the following link to verify your account:<br><a href='"+url+"'>"+url+"</a><br><br><br><br><a href='https://recoeve.net/'>Recoeve.net</a> 가입을 환영합니다.<br><br>계정 이메일 인증을 위해 로그인 후 다음 링크를 클릭해 주세요.:<br><a href='"+url+"'>"+url+"</a><br></span>"; NaverMail.send(email, "", title, msg); } private static final String username="kipid84"; private static final String amho="amho"; private static final Properties prop = new Properties(); static { prop.put("mail.smtp.host", "smtp.naver.com"); prop.put("mail.smtp.port", "587"); prop.put("mail.smtp.auth", "true"); prop.put("mail.smtp.starttls.enable", "true"); // TLS } private static final Session session = Session.getInstance( prop, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, amho); } } ); /** * Send email using NaverMail SMTP server. * * @param recipientEmail TO recipient * @param ccEmail CC recipient. Can be empty if there is no CC recipient * @param title title of the message * @param message message to be sent * @throws AddressException if the email address parse failed * @throws MessagingException if the connection is dead or not in the connected state or if the message is not a MimeMessage */ public static void send(String recipientEmail, String ccEmail, String title, String message) throws AddressException, MessagingException { try { Message msg = new MimeMessage(session); msg.setFrom(new InternetAddress("kipid84@naver.com")); msg.setRecipients( Message.RecipientType.TO, InternetAddress.parse(recipientEmail) ); msg.setSubject(title); msg.setContent(message, "text/html; charset=utf-8"); Transport.send(msg); } catch (MessagingException e) { e.printStackTrace(); } } public static void main(String... args) throws Exception { NaverMail.sendVeriKey("kipid84@naver.com", "kipid", "dfij378asd91fa9sdf1kraq9defr134nr913hjred9af"); NaverMail.sendChangePwd("kipid", "kipid84@naver.com", "29riw7fus8dfu8348u48f8uf", "ko"); } } ```/ ### Error in AWS server Windows firewall 도 다 열어보고 별 짓을 다 해 봤는데도 해결이 안됨 ㅡ,.ㅡ;;; Security 어쩌구에서 뭔가 막고 있나???
AWS Windows Server specification/version
```[.scrollable.lang-java] Compiling NaverMail.java --- OUTPUT: recoeve.http.NaverMail --- com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.naver.com, 587; timeout -1; nested exception is: java.net.ConnectException: Connection timed out: 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:388) 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 recoeve.http.NaverMail.send(NaverMail.java:90) at recoeve.http.NaverMail.sendVeriKey(NaverMail.java:47) at recoeve.http.NaverMail.main(NaverMail.java:97) Caused by: java.net.ConnectException: Connection timed out: connect at java.base/sun.nio.ch.Net.connect0(Native Method) at java.base/sun.nio.ch.Net.connect(Net.java:580) at java.base/sun.nio.ch.Net.connect(Net.java:569) at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:576) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) at java.base/java.net.Socket.connect(Socket.java:666) at java.base/java.net.Socket.connect(Socket.java:600) at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:359) at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238) at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175) ... 9 more com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.naver.com, 587; timeout -1; nested exception is: java.net.ConnectException: Connection timed out: 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:388) 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 recoeve.http.NaverMail.send(NaverMail.java:90) at recoeve.http.NaverMail.sendChangePwd(NaverMail.java:39) at recoeve.http.NaverMail.main(NaverMail.java:98) Caused by: java.net.ConnectException: Connection timed out: connect at java.base/sun.nio.ch.Net.connect0(Native Method) at java.base/sun.nio.ch.Net.connect(Net.java:580) at java.base/sun.nio.ch.Net.connect(Net.java:569) at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:576) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) at java.base/java.net.Socket.connect(Socket.java:666) at java.base/java.net.Socket.connect(Socket.java:600) at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:359) at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238) at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175) ... 9 more [Finished in 48.8s] ```/ ### Error in Vert.x server running on AWS now. ```[.scrollable.lang-java] com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.naver.com, 587; timeout -1; nested exception is: java.net.ConnectException: Connection timed out: 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:388) 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 recoeve.http.NaverMail.send(NaverMail.java:90) at recoeve.http.NaverMail.sendChangePwd(NaverMail.java:39) at recoeve.db.RecoeveDB.forgotPwd(RecoeveDB.java:784) at recoeve.http.Recoeve.lambda$start$16(Recoeve.java:594) at io.vertx.core.impl.future.FutureImpl$1.onSuccess(FutureImpl.java:91) at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60) at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211) at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23) at io.vertx.core.http.impl.HttpEventHandler.handleEnd(HttpEventHandler.java:79) at io.vertx.core.http.impl.Http2ServerRequest.handleEnd(Http2ServerRequest.java:198) at io.vertx.core.http.impl.Http2ServerStream.handleEnd(Http2ServerStream.java:198) at io.vertx.core.http.impl.VertxHttp2Stream.lambda$new$1(VertxHttp2Stream.java:62) at io.vertx.core.streams.impl.InboundBuffer.handleEvent(InboundBuffer.java:255) at io.vertx.core.streams.impl.InboundBuffer.write(InboundBuffer.java:134) at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:55) at io.vertx.core.impl.DuplicatedContext.emit(DuplicatedContext.java:158) at io.vertx.core.http.impl.VertxHttp2Stream.onEnd(VertxHttp2Stream.java:140) at io.vertx.core.http.impl.Http2ServerStream.onEnd(Http2ServerStream.java:123) at io.vertx.core.http.impl.VertxHttp2Stream.onEnd(VertxHttp2Stream.java:135) at io.vertx.core.http.impl.Http2ConnectionBase.onDataRead(Http2ConnectionBase.java:317) at io.vertx.core.http.impl.Http2ServerConnection.onDataRead(Http2ServerConnection.java:44) at io.netty.handler.codec.http2.Http2FrameListenerDecorator.onDataRead(Http2FrameListenerDecorator.java:36) at io.netty.handler.codec.http2.Http2EmptyDataFrameListener.onDataRead(Http2EmptyDataFrameListener.java:49) at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder$FrameReadListener.onDataRead(DefaultHttp2ConnectionDecoder.java:307) at io.netty.handler.codec.http2.DefaultHttp2FrameReader.readDataFrame(DefaultHttp2FrameReader.java:415) at io.netty.handler.codec.http2.DefaultHttp2FrameReader.processPayloadState(DefaultHttp2FrameReader.java:250) at io.netty.handler.codec.http2.DefaultHttp2FrameReader.readFrame(DefaultHttp2FrameReader.java:159) at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder.decodeFrame(DefaultHttp2ConnectionDecoder.java:173) at io.netty.handler.codec.http2.DecoratingHttp2ConnectionDecoder.decodeFrame(DecoratingHttp2ConnectionDecoder.java:63) at io.netty.handler.codec.http2.Http2ConnectionHandler$FrameDecoder.decode(Http2ConnectionHandler.java:393) at io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:453) at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529) at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) at io.vertx.core.http.impl.VertxHttp2ConnectionHandler.channelRead(VertxHttp2ConnectionHandler.java:416) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1383) at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1246) at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1295) at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529) at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Thread.java:1623) Caused by: java.net.ConnectException: Connection timed out: connect at java.base/sun.nio.ch.Net.connect0(Native Method) at java.base/sun.nio.ch.Net.connect(Net.java:580) at java.base/sun.nio.ch.Net.connect(Net.java:569) at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:576) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) at java.base/java.net.Socket.connect(Socket.java:666) at java.base/java.net.Socket.connect(Socket.java:600) at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:359) at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238) at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175) ... 66 more ```/ ## RRA
  1. https://mvnrepository.com/artifact/com.sun.mail/jakarta.mail/2.0.1
  2. javamail.java.net - API docs - Package com.sun.mail.smtp summary
  3. developers.google.com - Google App Engine - Java - Using JavaMail to Send Mail
  4. stackoverflow.com - Send email using java, 2010-09-06, asked by Mohit Bansal.
    // I used the answer by Cheok Yan Cheng. The code is written by doraemon (the same person??).
반응형