Java EE and JPA under Glassfish, NoClassDefFound com/mysql/jdbc/ResultSetMetaData - mysql

I have a problem when I acces my MySql Database from an EJB. After deploying my EAR to the Glassfish server, and calling the method that use the entity class I get an exception like this:
java.lang.NoClassDefFoundError: com/mysql/jdbc/ResultSetMetaData
I am using a local MySql Database, the connection to these still works. To acces the tables of these Databese I am using entity classes generated by Netbeans. This classes are situated in external Library (OthelloLibrarie). Here you can also find the remote interface of my Session Bean.
I had to put the entity classes in an external library because I'm using them in an Enterprise Client Application which is connected to my EAR.
My Enterprise Application Project contains the main Session bean and somes Session beans from entity classes which uses my entity classes in the external Library. It also contains the persistence XML and it includes my JDBC driver:
The error appears when I call the method createPartie from the Client Application:
Partie p = eJBOthelloGame.createPartie(jTextFieldPseudo.getText());
SessionBeanOthelloRemote.java:
#Stateless
public class SessionBeanOthello implements SessionBeanOthelloRemote {
#EJB
private PlayerFacadeLocal playerFacade;
#EJB
private PartieFacadeLocal partieFacade;
#Override
public Partie createPartie(String player) {
//Ajout du tuple
Partie p = new Partie();
Player p1 = new Player();
p1.setId(1);
p1.setNom(player);
playerFacade.create(p1);
p.setPlayer1(p1);
partieFacade.create(p);
return p;
}
Partie and Player are Entity classes used with generated facades.
I searched yet on the web but I never found this kind of error. It seems that only the package or class ResultSetMetaData from JDBC has a problem and not the entire driver.
Can you help me?

You need to include in your project the mysql-connector-java.jar file that provides the MySql JDBC driver classes. As you are using Netbeans, just add it as a library jar.
You can find it, along with download and installation instructions, at this link.

Related

Injecting DbContext into FileProvider in ASP.NET Core

I am trying to load some of the views from the database as described in here. So I want to use EF Core in the File provider.
RazorViewEngineOptions has a FileProviders property that you can add your file provider to. The problem is that you have to give it an instace of the file provider. So you'll need to instantiate all of the file providers' dependencies right there in Startup's ConfigureServices method.
Currently I inject an instance of IServiceProvider into the Configure method of Startup. Then I store the instance in a field (called _serviceProvider):
IServiceProvider _serviceProvider;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider provider)
{
_serviceProvider = provider;
...
}
Then in ConfigureServices I use that field to instanciate the UIDbContext.
services.Configure<RazorViewEngineOptions>(options =>
{
var fileProvider = new DbFileProvider(_serviceProvider.GetService<UIDbContext>());
options.FileProviders.Add(fileProvider);
});
Is there any better way to be able to inject the UIDbContext into the DbFileProvider constructor Or any way to instantiate a UIDbContext inside DbFileProvider without IServiceProvider?
You don't want to use DbContext as a file provider source the way you did.
DbContext isn't thread-safe, so it won't work when you have one single DbContext instance for the whole provider, because multiple requests could call the DbContext and it's operation more than once at the same time, resulting in exception when trying to execute 2 queries in parallel.
You'd have to instantiate a connection (like in the linked article) or DbContext per IFileInfo/IDirectoryContents instance.
DbContextOptions<UIDbContext> should be registered as singleton, so you can resolve it onceinside Configure` w/o any issues and pass it to your provider.
Alternatively you can also call DbContextOptionsBuilder and build/construct a DbContextOptions<T>, but then you have to repeat the configuration for you did inside AddDbContext (i.e. .UseSqlServer()).
However it can be useful, as it allows you to set different settings (i.e. changing the way how includes, errors etc. are logged).

Connection with mysql with netbeans for jsp [duplicate]

This question already has answers here:
The infamous java.sql.SQLException: No suitable driver found
(21 answers)
How should I connect to JDBC database / datasource in a servlet based application?
(2 answers)
Closed 2 years ago.
I am using NetBeans 7.0.1 IDE for JSP/servlet
I am trying to make a database connection for my project. Already downloaded the jar file 'mysql-connector-java-5.1.24-bin.jar' pasted it to jdk's jre/lib dir, also added it to my netbean projects libraries dir.
then I created a servlet and wrote the following code:
import java.sql.*;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class tstJDBC extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
String dbURL = "jdbc:mysql://localhost:3306/murach";
String username="root";
String password="1234";
Connection con2 = DriverManager.getConnection(dbURL, username, password);
String query = "insert into tblUser1(firstname) values('shaon')";
Statement statmnt = con2.createStatement();
statmnt.executeUpdate(query);
}
catch(SQLException e)
{
e.printStackTrace();
}
}
}
But it can establish the connection. From the line Connection con2, its directly going to catch() block ; without executing the query.
Try loading the driver prior to using the DriverManager class.
try{
String dbURL = "jdbc:mysql://localhost:3306/murach";
String username="root";
String password="1234";
Class.forName("com.mysql.jdbc.Driver");//load driver
Connection con2 = DriverManager.getConnection(dbURL, username, password);
String query = "insert into tblUser1(firstname) values('shaon')";
Statement statmnt = con2.createStatement();
statmnt.executeUpdate(query);
}
From O'Reilly:
Before you can use a driver, it must be registered with the JDBC
DriverManager. This is typically done by loading the driver class
using the Class.forName( ) method:
This is required since you have placed the library within the JDK/lib folder which I'm assuming is loaded using a different ClassLoader than the one used by your application. Since different class loaders were used the automatic registration that takes place by JDBC 4.0+ drivers will not take effect. You could try to place the driver jar file within the lib of your application server, which should use the same ClassLoader of your application. See: When is Class.forName needed when connecting to a database via JDBC in a web app?
Regarding Automatic Registration
In JDBC 4.0, we no longer need to explicitly load JDBC drivers using
Class.forName(). When the method getConnection is called, the
DriverManager will attempt to locate a suitable driver from among the
JDBC drivers that were loaded at initialization and those loaded
explicitly using the same class loader as the current application.
The DriverManager methods getConnection and getDrivers have been
enhanced to support the Java SE Service Provider mechanism (SPM).
According to SPM, a service is defined as a well-known set of
interfaces and abstract classes, and a service provider is a specific
implementation of a service. It also specifies that the service
provider configuration files are stored in the META-INF/services
directory. JDBC 4.0 drivers must include the file
META-INF/services/java.sql.Driver. This file contains the name of the
JDBC driver's implementation of java.sql.Driver. For example, to load
the JDBC driver to connect to a Apache Derby database, the
META-INF/services/java.sql.Driver file would contain the following
entry:
org.apache.derby.jdbc.EmbeddedDriver
Let's take a quick look at how we can use this new feature to load a
JDBC driver manager. The following listing shows the sample code that
we typically use to load the JDBC driver. Let's assume that we need to
connect to an Apache Derby database, since we will be using this in
the sample application explained later in the article:
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
Connection conn =
DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword);
But in JDBC 4.0, we don't need the Class.forName() line. We can simply
call getConnection() to get the database connection.
Source
Regarding Service Loaders
For the purpose of loading, a service is represented by a single
type, that is, a single interface or abstract class. (A concrete class
can be used, but this is not recommended.) A provider of a given
service contains one or more concrete classes that extend this service
type with data and code specific to the provider. The provider class
is typically not the entire provider itself but rather a proxy which
contains enough information to decide whether the provider is able to
satisfy a particular request together with code that can create the
actual provider on demand. The details of provider classes tend to be
highly service-specific; no single class or interface could possibly
unify them, so no such type is defined here. The only requirement
enforced by this facility is that provider classes must have a
zero-argument constructor so that they can be instantiated during
loading.
A service provider is identified by placing a provider-configuration
file in the resource directory META-INF/services. The file's name is
the fully-qualified binary name of the service's type. The file
contains a list of fully-qualified binary names of concrete provider
classes, one per line. Space and tab characters surrounding each name,
as well as blank lines, are ignored. The comment character is '#'
('\u0023', NUMBER SIGN); on each line all characters following the
first comment character are ignored. The file must be encoded in
UTF-8.
If a particular concrete provider class is named in more than one
configuration file, or is named in the same configuration file more
than once, then the duplicates are ignored. The configuration file
naming a particular provider need not be in the same jar file or other
distribution unit as the provider itself. The provider must be
accessible from the same class loader that was initially queried to
locate the configuration file; note that this is not necessarily the
class loader from which the file was actually loaded.
Source
just Keep the "mysql-connector-java" in "C:\Program Files\Java\jdk1.7.0_25\jre\lib\ext"
the "jdk1.7.0_25" is my version of jdk may be you have different version but will must have the sub folders "\jre\lib\ext" inside that.

CloudFoundry MySQL Java configuration

I have a Spring MVC app that is running fine on local tomcat etc. Its a Spring 3.1 MVC/Hibernate app.
I am using (where possible) pure Java #Configuration for the app - and I am now trying to deploy the app to CloudFoundry (via STS), but I am struggling to get the MySql db configured (from memory, with xml config you dont need to do anything and Spring/CloudFoundry auto-injects the required user/password etc, but its been a while since I deployed anything to CF).
I have tried both of the following configurations:
#Bean
public BasicDataSource dataSource() throws PropertyVetoException {
//CloudFoundry config
final CloudEnvironment cloudEnvironment = new CloudEnvironment();
final List<MysqlServiceInfo> mysqlServices = cloudEnvironment.getServiceInfos(MysqlServiceInfo.class);
final MysqlServiceInfo serviceInfo = mysqlServices.get(0);
BasicDataSource bean = new BasicDataSource();
bean.setDriverClassName("com.mysql.jdbc.Driver");
bean.setUrl(serviceInfo.getUrl());
bean.setUsername(serviceInfo.getUserName());
bean.setPassword(serviceInfo.getPassword());
return bean;
}
The above failed on out of bounds on the .get(0) line of the mysqlServices. This was based on the answer suggested here.
I also tried leaving the datasource as what it runs on as local to see if the properties just get injected, but no luck there either. (the below was tried with the values as per the Spring sample code here, and also using property placeholders from my db.connection props file)
#Bean
public BasicDataSource dataSource() throws PropertyVetoException {
BasicDataSource bean = new BasicDataSource();
bean.setDriverClassName("com.mysql.jdbc.Driver");
bean.setUrl("");
bean.setUsername("spring");
bean.setPassword("spring");
return bean;
}
Edit
I have also used the getServiceInfo(String, Class) method passing in the name of the MySql service that I have created and bound to the application, but that just NPEs similar to the getServiceInfos(..) approach
Ok, this was just a stupid mistake - when I deployed the app via STS I had selected Java Web app rather than the "Spring" type. Not sure why that would make the CloudEnvironment properties not be available (I was under the impression that approach was the common method to inject the details in non-Spring apps) - but re-deploying it to the server as a Spring app resolved the probs!

RESTful web service: java.lang.NullPointerException service.AbstractFacade.findAll

I created a simple XML web service using NetBeans 7's "RESTful Web Services from Database..." wizard. At this point, I want to publish a list of users from the associated mySQL database.
When I attempt to access the service via its URL (http://localhost:8080/database/resources/users), I get an error that reads "java.lang.NullPointerException". The stack trace:
service.AbstractFacade.findAll(AbstractFacade.java:41)
service.UserFacade.findAll(UserFacade.java:51)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:165)
com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:67)
com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:276)
com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:83)
com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:133)
com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:71
com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1171) com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1103) com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1053)
com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1043)
com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:406)
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:477)
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:662)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
User entity:
package entities;
...
#Entity
#Table(name="users")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
...
I've also changed the named query to User.findAll in case the names needs to align with the entity's name. This did not solve the problem.
I'm not certain if it is 'normal' or not, but the wizard created a fairly sparse UserFacade class; I added the missing methods after researching the topic. Furthermore, the javax.ejb.Stateless package seems to be missing (perhaps not on my workstation's CLASSPATH); this is the reason that the #Stateless annotation is disabled.
UserFacade class:
//#Stateless
#Path("users")
public class UserFacade extends AbstractFacade<User> {
#PersistenceContext(unitName="databasePU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public UserFacade() {
super(User.class);
}
#GET
#Path("{id}")
#Produces({"application/xml", "application/json"})
public User find(#PathParam("id") BigDecimal id) {
return super.find(id);
}
#GET
#Override
#Produces({"application/xml", "application/json"})
public List<User> findAll() {
return super.findAll();
}
}
Exception is thrown at the first line in the AbstractFacade's findAll method:
public List<T> findAll() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
...
}
Questions:
Is the #Stateless annotation required for this to function?
Does this pattern require J2EE 6 rather than J2SE 6 (which is what is installed on my OS X workstation)? The 'javax.ejb' namespace seems to suggest enterprise java beans.
** edit **
Java SE 6 (1.6.0_29-b11-402)
The auto-generated query "SELECT u FROM Users u" works without any problems. As per the comment suggesting that "u" might be wrong because it doesn't represent a column, that suggestion is not correct because here "u" is an alias for the table users.
I would debug further the findAll() to check if something is null, i.e. the EntityManager.
The #Stateless annotation in the UserFacade is necessary, and removing it would probably cause the EntityManager to be null (note that I wrote "removing" because NetBeans places if for you, if you use "RestFul Web Services from Database" wizard). See here a similar question.
Regarding your latest edit: yes, these features need to be built using the Java Platform, Enterprise Edition. In particular, RESTFul web services make use of the Java API for RESTful Web Services (JAX-RS) which is included in the Java EE 6 platform as explained here.
GlassFish Server Open Source Edition is the first compatible implementation of the Java EE 6 platform specification: I suggest using this Application Server and following the tutorials linked above.
I think #ori is on the the answer. Your table Users probably don't have a column named u so you get an exception when it tries to match the column u to the database.
Change to u.* and it should work fine.

How to setup JUnit tests for Glassfish Embeddable EJBContainer + EclipseLink JPA?

I'm trying to use EJB 3.1 Embeddable EJBContainer on Glassfish 3.1 for integration
testing my EJB's. There's a classloading issue I can't figure out.
My ejbs are build into dum-ejb.jar. They use EclipseLink JPA. I also create EJB client jar dum-ejb-client.jar, while attempting to fight the classloading issues. Client jar contains the EJB interfaces, and Entity classes (which are usually parameters or returns values). Client jar also contains a lot of unneeded classes that could be dropped (but I don't see how it would solve the problem).
The problem is that since EclipseLink does bytecode weaving to the Entity classes, the Entity classes must not be in the classpath when the junit tests are run: http://www.java.net/forum/topic/glassfish/glassfish/embedded-glassfish-and-weaving
I can do that and configure classpath so that dum-ejb.jar is not included. If I use EJBContainer so that I look up my service as a java.lang.Object and call it's methods via reflection, the test works. But of course, that's not how I want to write my tests.
Typical test would be like:
#Test
public void testInEJBContainer() throws Exception {
File ejbJarFile = new File("target/dum/dum-ejb.jar");
Map props = new HashMap();
props.put("org.glassfish.ejb.embedded.glassfish.instance.root",
"target/classes/instance-root");
props.put(EJBContainer.MODULES, new File[]{ejbJarFile});
EJBContainer container = EJBContainer.createEJBContainer(props);
CompanyService = (CompanyService)
container.getContext().lookup("java:global/dum/CompanyServiceImpl");
log.info("result of findAll() " + service.findAll(false));
}
How could I run the test if CompanyService interface, and returned Company Entity classes can not be in the classpath?
Even if dum-ejb.jar is not on classpath, and dum-ejb-client.jar is, EclipseLink weaving gets broken.
Isn't this exactly the typical use case for EJBContainer, shouldn't there be a simple solution to this?
Turns out I ran into classloading problems since I was running the EJBContainer from maven ear project.
When I run it from the maven ejb project itself, there's no such issues and EJBContainer is easy to use.