英文:
java.lang.ClassNotFoundException: Didn't find class "com.sun.mail.util.MailLogger" on path:
问题
以下是翻译好的内容:
ForgotPasswordAcivity.java
public class ForgotPasswordActivity extends AppCompatActivity {
EditText getNumberEditText;
int generatedNumber;
protected void sendEmail() {
Random random = new Random();
generatedNumber = random.nextInt(10000 - 1001) + 1001;
new Thread(new Runnable() {
@Override
public void run() {
try {
GMailSender sender = new GMailSender("sample@gmail.com",
"1234");
sender.sendMail("更改密码的代码 - Stairways to Solutions", "您的代码是 " + generatedNumber,
"sample@gmail.com", "user@gmail.com");
} catch (Exception e) {
Log.e("SendMail", e.getMessage(), e);
}
}
}).start();
}
public void send(View view){
sendEmail();
}
public void check(View view){
if (getNumberEditText.getText().toString().equals(Integer.toString(generatedNumber))){
Toast.makeText(this, "给出了正确的代码!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "请检查代码", Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forgot_password);
getNumberEditText = findViewById(R.id.getNumberEditText);
}
}
GMailSender.java
class GMailSender extends javax.mail.Authenticator {
private String mailhost = "smtp.gmail.com"; // 邮件服务器的主机名,用于连接发送邮件的SMTP服务器。
private String user;
private String password;
private Session session;
static {
Security.addProvider(new JSSEProvider());
}
public GMailSender(String user, String password) {
this.user = user; // 您的SMTP用户名。对于GMail SMTP,这将是您的GMail电子邮件地址。
this.password = password; // 您的SMTP密码。对于GMail SMTP,这将是您的GMail密码。
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", mailhost);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.quitwait", "false");
session = Session.getDefaultInstance(props, this);
}
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password);
}
public synchronized void sendMail(String subject, String body,
String sender, String recipients) throws Exception {
MimeMessage message = new MimeMessage(session);
DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain"));
message.setSender(new InternetAddress(sender));
message.setSubject(subject);
message.setDataHandler(handler);
if (recipients.indexOf(',') > 0)
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));
else
message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients));
Transport.send(message);
}
}
JSSEProvider.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @author Alexander Y. Kleymenov
* @version $Revision$
*/
import java.security.AccessController;
import java.security.Provider;
public final class JSSEProvider extends Provider {
public JSSEProvider() {
super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {
public Void run() {
put("SSLContext.TLS",
"org.apache.harmony.xnet.provider.jsse.SSLContextImpl");
put("Alg.Alias.SSLContext.TLSv1", "TLS");
put("KeyManagerFactory.X509",
"org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl");
put("TrustManagerFactory.X509",
"org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl");
return null;
}
});
}
}
build.gradle:Project
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "com.luv.stairwaystosolutions"
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
dexOptions {
javaMaxHeapSize "4g"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.parse.bolts:bolts-tasks:1.4.0'
implementation 'com.parse:parse-android:1.17.3'
implementation 'androidx.multidex:multidex:2.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0-beta01'
implementation 'javax.mail:javax.mail-api:1.5.3'
}
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")) {
details.useVersion '25.3.1'
}
}
}
}
build.gradle:Module
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
mavenCentral()
jcenter()
google()
maven {
url 'https://maven.google.com/'
name 'Google'
}
}
dependencies {
classpath '
<details>
<summary>英文:</summary>
I am making an app in which an email will be sent to user's gmail id when a button is clicked. This is the following code of needed classes.
**ForgotPasswordAcivity.java**
public class ForgotPasswordActivity extends AppCompatActivity {
EditText getNumberEditText;
int generatedNumber;
protected void sendEmail() {
Random random = new Random();
generatedNumber = random.nextInt(10000 - 1001) + 1001;
new Thread(new Runnable() {
@Override
public void run() {
try {
GMailSender sender = new GMailSender("sample@gmail.com",
"1234");
sender.sendMail("Code for Changing Password in Stairways to Solutions", "Your Code is " + generatedNumber,
"sample@gmail.com", "user@gmail.com");
} catch (Exception e) {
Log.e("SendMail", e.getMessage(), e);
}
}
}).start();
}
public void send(View view){
sendEmail();
}
public void check(View view){
if (getNumberEditText.getText().toString().equals(Integer.toString(generatedNumber))){
Toast.makeText(this, "Correct Number given!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Check the Number", Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forgot_password);
getNumberEditText = findViewById(R.id.getNumberEditText);
}
}
**GMailSender.java**
class GMailSender extends javax.mail.Authenticator {
private String mailhost = "smtp.gmail.com"; //Hostname of the SMTP mail server which you want to connect for sending emails.
private String user;
private String password;
private Session session;
static {
Security.addProvider(new JSSEProvider());
}
public GMailSender(String user, String password) {
this.user = user; //Your SMTP username. In case of GMail SMTP this is going to be your GMail email address.
this.password = password; //Your SMTP password. In case of GMail SMTP this is going to be your GMail password.
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", mailhost);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.quitwait", "false");
session = Session.getDefaultInstance(props, this);
}
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password);
}
public synchronized void sendMail(String subject, String body,
String sender, String recipients) throws Exception {
MimeMessage message = new MimeMessage(session);
DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain"));
message.setSender(new InternetAddress(sender));
message.setSubject(subject);
message.setDataHandler(handler);
if (recipients.indexOf(',') > 0)
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));
else
message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients));
Transport.send(message);
}
}
**JSSEProvider.java**
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @author Alexander Y. Kleymenov
* @version $Revision$
*/
import java.security.AccessController;
import java.security.Provider;
public final class JSSEProvider extends Provider {
public JSSEProvider() {
super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {
public Void run() {
put("SSLContext.TLS",
"org.apache.harmony.xnet.provider.jsse.SSLContextImpl");
put("Alg.Alias.SSLContext.TLSv1", "TLS");
put("KeyManagerFactory.X509",
"org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl");
put("TrustManagerFactory.X509",
"org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl");
return null;
}
});
}
}
build.gradle:Project
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "com.luv.stairwaystosolutions"
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
dexOptions {
javaMaxHeapSize "4g"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.parse.bolts:bolts-tasks:1.4.0'
implementation 'com.parse:parse-android:1.17.3'
implementation 'androidx.multidex:multidex:2.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0-beta01'
implementation 'javax.mail:javax.mail-api:1.5.3'
}
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")) {
details.useVersion '25.3.1'
}
}
}
}
build.gradle:Module
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
mavenCentral()
jcenter()
google()
maven {
url 'https://maven.google.com/'
name 'Google'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.4'
}
}
allprojects {
repositories {
mavenCentral()
maven {
url 'https://maven.google.com/'
name 'Google'
}
}
}
ext {
compileSdkVersion = 27
buildToolsVersion = "27.0.3"
minSdkVersion = 14
targetSdkVersion = 23
}
I have added the activation.jar, additional.jar and mail.jar in libs folder.
[![libs Folder][1]][1]
Error :
2020-09-21 19:13:36.868 16758-16809/com.luv.stairwaystosolutions E/AndroidRuntime: FATAL EXCEPTION: Thread-2
Process: com.luv.stairwaystosolutions, PID: 16758
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/sun/mail/util/MailLogger;
at javax.mail.Session.initLogger(Session.java:226)
at javax.mail.Session.<init>(Session.java:210)
at javax.mail.Session.getDefaultInstance(Session.java:321)
at com.luv.stairwaystosolutions.GMailSender.<init>(GMailSender.java:38)
at com.luv.stairwaystosolutions.ForgotPasswordActivity$1.run(ForgotPasswordActivity.java:33)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.sun.mail.util.MailLogger" on path: DexPathList[[zip file "/data/app/com.luv.stairwaystosolutions-1/base.apk"],nativeLibraryDirectories=[/data/app/com.luv.stairwaystosolutions-1/lib/x86_64, /system/lib64, /vendor/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at javax.mail.Session.initLogger(Session.java:226) 
at javax.mail.Session.<init>(Session.java:210) 
at javax.mail.Session.getDefaultInstance(Session.java:321) 
at com.luv.stairwaystosolutions.GMailSender.<init>(GMailSender.java:38) 
at com.luv.stairwaystosolutions.ForgotPasswordActivity$1.run(ForgotPasswordActivity.java:33) 
at java.lang.Thread.run(Thread.java:761) 
This is the error line :
session = Session.getDefaultInstance(props, this);
Thank you in advance for help.
[1]: https://i.stack.imgur.com/Gf5Jd.png
</details>
# 答案1
**得分**: 1
**build.gradle:Project**
```gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "com.luv.stairwaystosolutions"
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
dexOptions {
javaMaxHeapSize "4g"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.parse.bolts:bolts-tasks:1.4.0'
implementation 'com.parse:parse-android:1.17.3'
implementation 'androidx.multidex:multidex:2.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0-beta01'
implementation 'javax.mail:javax.mail-api:1.5.3'
implementation group: 'com.sun.mail', name: 'javax.mail', version: '1.6.2'
}
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")) {
details.useVersion '25.3.1'
}
}
}
}
英文:
build.gradle:Project
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "com.luv.stairwaystosolutions"
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
dexOptions {
javaMaxHeapSize "4g"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.parse.bolts:bolts-tasks:1.4.0'
implementation 'com.parse:parse-android:1.17.3'
implementation 'androidx.multidex:multidex:2.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0-beta01'
implementation 'javax.mail:javax.mail-api:1.5.3'
implementation group: 'com.sun.mail', name: 'javax.mail', version: '1.6.2'
}
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")) {
details.useVersion '25.3.1'
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论