I am trying to send an email using the JavaMail API. Here is my code on the servlet:
package com.lsp.web;
import com.lsp.service.Mailer;
import javax.ejb.EJB;
import javax.mail.MessagingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
#WebServlet(name = "contact", urlPatterns = {"/contact"})
public class ContactServlet extends SpringInjectedServlet {
#EJB
private Mailer emailBean;
#Override
public void init() throws ServletException {
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String customerEmail = req.getParameter("email");
String subject = req.getParameter("subject");
String body = req.getParameter("message");
String error = null;
String succMess = null;
try {
javax.mail.internet.InternetAddress ia = new javax.mail.internet.InternetAddress(customerEmail);
ia.validate();
emailBean.send(customerEmail, subject, body);
req.setAttribute("succMessage", succMess);
req.getRequestDispatcher("sent.jsp").forward(req, resp);
} catch (javax.mail.internet.AddressException ae) {
error = "您指出的邮箱地址不存在";
req.setAttribute("errorMessage", error);
req.getRequestDispatcher("contact.jsp").forward(req, resp);
}
catch (MessagingException mex) {
error = "发送失败";
req.setAttribute("errorMessage", error);
req.getRequestDispatcher("contact.jsp").forward(req, resp);
}
}
}
At the line where I check for the user address where:
javax.mail.internet.InternetAddress ia = new javax.mail.internet.InternetAddress(customerEmail);
ia.validate();
I got an exception.
java.lang.NoClassDefFoundError: Could not initialize class javax.mail.internet.InternetAddress
In pom.xml, I added these lines:
<!--JavaMail API-->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.5.1</version>
</dependency>
<!--EJB-->
<dependency>
<groupId>javax.ejb</groupId>
<artifactId>ejb-api</artifactId>
<version>3.0</version>
</dependency>
I am using Tomcat.
Could someone tell me why this happens and how I can solve the issue.
Thank you.
Please see: https://stackoverflow.com/a/28935760/1128668 You have included the mail-api.jar in your project. That's the API specification only. The fix is to replace this:
<!-- DO NOT USE - it's just the API, not an implementation -->
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
with the reference implementation of that api:
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
I know it has sun in the package name, but that's the latest version.
You get a java.lang.NoClassDefFoundError, which means that the JVM can't initialise the class, not that it can't find the class which would be a ClassNotFoundException. A NoClassDefFoundError can be caused by a ClassNotFoundException but that need not be the case.
In order to find the cause, stop the server, delete the log and start again. Then reproduce the error and try to find the first Exception and its cause in your log file. If you are lucky this is the cause for the NoClassDefFoundError.
You also might indicate in your question which server you are using. It might make a difference how to solve the error.
Adding the dependency at build time does nothing to make the dependency available to Tomcat at runtime. You need to add the javax.mail.jar file to the WEB-INF/lib directory of your application, or to Tomcat's lib directory.
Of course, you wouldn't have this problem if you were using a full Java EE application server instead of Tomcat... :-)
Related
To add it I tried sevral methods that I found online but none of them worked for me.
Here is how I try to import the driver:
1- I tried the method in the answer : Correct way to add external jars (lib/*.jar) to an IntelliJ IDEA project
2- I go to File ==> Project Structure==> Libraries then I add the mysql connecter .jar
Here is my Java class for the connection :
package dao;
import java.sql.Connection;
import java.sql.DriverManager;
public class DbConnection {
private static Connection connection;
static {
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/supermarche", "root","password");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Connection getConnection() {
return connection;
}
}
my Servlet
package com.marcheli.shoping;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import user.Client;
import user.ManagementUser;
import java.io.IOException;
public class main extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ManagementUser manage = new ManagementUser();
//the class ManagementUser use the getConnection() method and performe operation in DB
Client c = manage.signUp(new Client("h","12334","email#sj",
"072737","ksk","jd"));
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}
In my web Browser, When I visit the URL for this Servlet I get this errors(it tells me the JDBC is not found):
java.lang.ExceptionInInitializerError
user.ManagementUser.signUp(ManagementUser.java:14)
com.marcheli.shoping.main.doGet(main.java:18)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:683)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:792)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
cause mère
java.lang.RuntimeException: java.lang.ClassNotFoundException:
com.mysql.jdbc.Driver dao.DbConnection.(DbConnection.java:16)
user.ManagementUser.signUp(ManagementUser.java:14)
com.marcheli.shoping.main.doGet(main.java:18)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:683)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:792)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
EDIT
I tried also to add the connector to my Artifact:
I am trying to connect my Servlet to mysql database using data Source . But whenever I run my servlet I end up getting this exception :
java.lang.AbstractMethodError: com.mysql.jdbc.Connection.isValid(I)Z
org.apache.tomcat.dbcp.dbcp2.DelegatingConnection.isValid(DelegatingConnection.java:913)
org.apache.tomcat.dbcp.dbcp2.PoolableConnection.validate(PoolableConnection.java:282)
org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory.validateConnection(PoolableConnectionFactory.java:356)
org.apache.tomcat.dbcp.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.java:2306)
org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2289)
org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2038)
org.apache.tomcat.dbcp.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1532)
Servlet.AbdulTayyebs.processRequest(AbdulTayyebs.java:36)
Servlet.AbdulTayyebs.doGet(AbdulTayyebs.java:57)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Here is my Content.xml
<Resource name="jdbc/abdultayyebs" auth="Container"
type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:4000/abdultayyebs?zeroDateTimeBehavior=convertToNull"
username="root" password="february1996" maxActive="5" maxIdle="2"
maxWait="1000"/>
Here is my web.xml
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/abdultayyebs</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth></resource-ref>
And here is my servlet AbdulTayyebs
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
public class AbdulTayyebs extends HttpServlet {
DataSource ds=null;
#Override
public void init(ServletConfig config)throws ServletException{
try {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
ds = (DataSource)envContext.lookup("jdbc/abdultayyebs");
} catch (Exception e) {
throw new ServletException("Something went wrong while Initializing the Servlet",e);
}
}
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException,IOException {
PrintWriter write = response.getWriter();
try {
Others.Action a = Others.ActionFactory.CreateAction(request);
try(Connection c=ds.getConnection()){
String page = a.Execute(c,request,request.getSession(false));
request.getRequestDispatcher(page).forward(request, response);
}
}
catch (SQLException e) {
write.println(e);
}
catch (ServletException e) {
write.println(e);
}
catch (Exception e) {
write.println(e);
}
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
I also added the mysql jdbc driver in the lib folder of tomcat but even this didnt helped ? It would be highly appreciable if anybody can help me out
java.lang.AbstractMethodError: com.mysql.jdbc.Connection.isValid(I)Z
This means that the MySQL JDBC driver is outdated as such that it doesn't support Java 1.6's Connection#isValid() method.
Upgrade it. And make sure that you've only one MySQL JDBC driver JAR file in the runtime classpath.
See also:
Connect Java to a MySQL database
For me, the solution was not to upgrade my driver (JT400). Even the latest version (9.1) appears to not have implemented isValid() (it's commented out in the code?).
What worked for me was to provide a validationQuery to my database connection pool. E.g.:
validationQuery=SELECT current date FROM sysibm.sysdummy1
net.sourceforge.jtds.jdbc.JtdsConnection doesn't implement isValid()
So you need to specify a connection-test-query to ensure that isValid() method isn't called
Adding the following line to application.propertiesfile resolved the error for me.
spring.datasource.hikari.connection-test-query=SELECT 1
in my case, I upgraded ojdbc from verion 14 to 6. I had artifact ojdbc14, then I changed it to ojdbc6. I lost quite sometime here, as I thought 14 is a later version as 14>6. but 14 is meant for java 1.4. 6 means java6
I was getting the same thing using jt400 for DB2 , this worked out for me
validationQuery="SELECT 1 FROM SYSIBM.SYSDUMMY1"
This is what I read about isValid method (source).
The driver (here MySQL) tries to check if your connection is valid or not.
Not sure how it works (as it doesn't allow to connect even when my MySQL instance/service is up and running).
So, use the below string in your spring application.properties file
spring.datasource.hikari.connection-test-query=select 1 from dual
(or any test query, - select sysdate from dual)
For me, I added the validationQuery parameter within the database connection pool config.
<Resource name="jdbc/abdultayyebs" auth="Container"
type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:4000/abdultayyebs?zeroDateTimeBehavior=convertToNull"
username="root" password="february1996" maxActive="5" maxIdle="2"
maxWait="1000" validationQuery="SELECT 1"/>
I'm trying to use google guice for dependency injection however I can't seem to wire everything togheter.
In my web.xml I defined the guiceFilter and the guiceListener like so:
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>backend.listener.GuiceConfigListener</listener-class>
</listener>
the config listener is basicly pretty simple:
#Override
protected Injector getInjector(){
return Guice.createInjector(new ServletModule(), new ArtsModule());
}
and the ArtsModule at this moment just has one binding like so:
#Override
protected void configure(){
bind(ArtsDAO.class).to(ArtsDAOGae.class);
}
I then continue to do a field injection of the ArtsDao in a service class:
#Inject
private ArtsDAO artsDAO;
But when I try to build my project (which is a maven build) I get a NPE on the artsDAO field, this most likely happens because the unit tests aren't running in a web environment.
Can anyone advice me on how to configure the guice bidings so that they are picked up during unit testing?
Thanks
Pip,
this is not trivial task but definitely you can achieve what you want.
First of all have a look at Tadedon project at https://code.google.com/p/tadedon
especially tadedon-guice-servlet-mock.
You will need something like fake container for your test. My fake container contains also Apache Shiro integration so you can throw it out, It looks like:
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.xemantic.tadedon.guice.servlet.mock.FakeServletContainer;
import com.xemantic.tadedon.guice.servlet.mock.FakeServletContainerModule;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.SubjectThreadState;
import org.apache.shiro.web.subject.WebSubject;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.Arrays;
public class FakeTestContainerInit {
private final FakeServletContainer servletContainer;
private final Injector internalInjector;
private Subject internalSubject;
public FakeTestContainerInit() {
this(new Module[] {});
}
public FakeTestContainerInit(Module... modules) {
super();
modules = Arrays.copyOf(modules, modules.length + 1);
modules[modules.length-1] = new FakeServletContainerModule();
internalInjector = Guice.createInjector(modules);
servletContainer = internalInjector.getInstance(FakeServletContainer.class);
}
public void start() throws ServletException, IOException {
this.start(true);
}
public void start(boolean initializeSecurityContext) throws ServletException, IOException {
getServletContainer().start();
MockHttpServletRequest request = servletContainer.newRequest("GET","/");
MockHttpServletResponse response = new MockHttpServletResponse();
if(initializeSecurityContext) {
SecurityManager scm = internalInjector.getInstance(SecurityManager.class);
internalSubject = new WebSubject.Builder(scm, request, response).buildWebSubject();
SubjectThreadState sts = new SubjectThreadState(internalSubject);
sts.bind();
} else { internalSubject = null; }
getServletContainer().service(request, response);
}
public void stop() {
servletContainer.stop();
}
public FakeServletContainer getServletContainer() {
return servletContainer;
}
public <T> T getInstance(final Class<T> type) throws IOException, ServletException {
return getServletContainer().getInstance(type);
}
public <T> T getInstance(final Key<T> key) throws IOException, ServletException {
return getServletContainer().getInstance(key);
}
public Subject getSubject() {
return internalSubject;
}
}
Dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.sonatype.sisu</groupId>
<artifactId>sisu-guice</artifactId>
</dependency>
<dependency>
<groupId>com.xemantic.tadedon</groupId>
<artifactId>tadedon-guice-servlet-mock</artifactId>
</dependency>
and Apache Shiro you won't need:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
</dependency>
All you need to do, is create FakeTestContainerInit and call start() and stop() method. Also all object creations have to be done via FakeTestContainerInit.getInstance method inside tests.
Well, I used it to test Vaadin application so I did not need sending requests and checking responses. So, this one you will need to implement. It can be done via getServletContainer().service(request, response);. But i think you will figure out. Hope it will help you.
So my next problem with this code. It seemse to not be finding a method and my eyes are untrained. Any help available on this?
package packeging;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.amazonaws.HttpMethod;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.auth.BasicAWSCredentials;
import org.apache.http.*;
/**
* Servlet implementation class Hashtastic
*/
#WebServlet("/Hashtastic")
public class Hashtastic extends HttpServlet {
private static final long serialVersionUID = 1L;
private final static String BUCKET_NAME = "idlatestingbucket";//http://s3.amazonaws.com/THESISDB/techy.jpg
private final static String FILE_NAME = "TestPicture/wallpaper-264411.png";
private final static String ACCESS_KEY = "Fakepass";
private final static String SECRET_KEY = "Fakekey";
/**
* Default constructor.
*/
public Hashtastic() {
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter out = response.getWriter();
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 1000);
Date expDate = cal.getTime();
out.println(expDate+"\n");
BasicAWSCredentials cre = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
AmazonS3 s3 = new AmazonS3Client(cre);
String url = s3.generatePresignedUrl(BUCKET_NAME, FILE_NAME, expDate, HttpMethod.GET).toString();
out.println(url);
out.close();
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
I am getting this 500 error. It says that it is missing a method. I have the jar in my lib and plugins for eclipse.
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Servlet execution threw an exception
root cause
java.lang.NoSuchMethodError: org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager: method <init>()V not found
com.amazonaws.http.ConnectionManagerFactory.createThreadSafeClientConnManager(ConnectionManagerFactory.java:26)
com.amazonaws.http.HttpClientFactory.createHttpClient(HttpClientFactory.java:83)
com.amazonaws.http.AmazonHttpClient.<init>(AmazonHttpClient.java:116)
com.amazonaws.AmazonWebServiceClient.<init>(AmazonWebServiceClient.java:60)
com.amazonaws.services.s3.AmazonS3Client.<init>(AmazonS3Client.java:291)
com.amazonaws.services.s3.AmazonS3Client.<init>(AmazonS3Client.java:273)
packeging.Hashtastic.doGet(Hashtastic.java:48)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.27 logs.
This could happen if you have the wrong version of the httpclient jar in your classpath, or if you have more than one version of that jar in your classpath (e.g. having both httpclient-4.0.1.jar and httpclient-4.1.1.jar).
It could also be caused by another jar containing a different version of the same class. For example, I know that gwt-dev.jar contains a version of ThreadSafeClientConnManager. If this is the case, the problem could probably be solved by adjusting the build path order to put httpclient.jar before gwt-dev.jar (or the other jar causing problem).
From experience with this exact same Exception, the chances are fairly good that it is caused by gwt-dev appearing before aws-java-sdk in your classpath and due to gwt-dev containing a conflicting (in terms of classloading) version of org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager
If you happen to be using Maven, re-order your dependencies as follows and perhaps add a warning to fellow maintainers on the significance of the ordering.
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.3.26</version>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<version>2.3.0</version>
</dependency>
i'm using a maven project with following dependency :
<dependency>
<groupId>com.google.api.client</groupId>
<artifactId>google-api-client-googleapis-auth-clientlogin</artifactId>
<version>1.2.3-alpha</version>
</dependency>
when i run following code:
import java.io.IOException;
import com.google.api.client.googleapis.GoogleTransport;
import com.google.api.client.googleapis.auth.clientlogin.ClientLogin;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.HttpTransport;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args ) throws IOException
{
HttpTransport transport = GoogleTransport.create();
// transport.addParser(new JsonCParser());
try {
// authenticate with ClientLogin
ClientLogin authenticator = new ClientLogin();
authenticator.authTokenType = "ndev";
authenticator.username = "....";
authenticator.password = "....";
authenticator.authenticate().setAuthorizationHeader(transport);
// make query request
HttpRequest request = transport.buildGetRequest();
request.setUrl("https://www.googleapis.com/bigquery/v1/query");
request.url.put(
"q", "select count(*) from [bigquery/samples/shakespeare];");
System.out.println(request.execute().parseAsString());
} catch (HttpResponseException e) {
System.err.println(e.response.parseAsString());
throw e;
}
}
}
i get below exception:
Exception in thread "main" java.lang.IllegalStateException: Missing required low-level HTTP transport package.
Use package "com.google.api.client.javanet".
at com.google.api.client.http.HttpTransport.useLowLevelHttpTransport(HttpTransport.java:129)
at com.google.api.client.http.HttpTransport.<init>(HttpTransport.java:187)
at com.google.api.client.googleapis.GoogleTransport.create(GoogleTransport.java:58)
at com.example.clientlogin.App.main(App.java:18)
what is the problem with GoogleTransport class?
Quick googeling resulted in maven for com.google.api.client.javanet.nethttpresponse Try adding
<dependency>
<groupId>com.google.api.client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.2.3-alpha</version>
</dependency>
or
<dependency>
<groupId>com.google.api.client</groupId>
<artifactId>google-api-client-javanet</artifactId>
<version>1.2.3-alpha</version>
</dependency>
to your POM file
this question is pretty old, but I've added some updates to our Java Google Client Lib + BigQuery samples (here: http://code.google.com/p/google-bigquery-tools/source/browse/samples/java/gettingstarted/BigQueryJavaGettingStarted/).