h2 数据库的 ClassNotFound 异常 class.forname("org.h2.Driver")

Posted

技术标签:

【中文标题】h2 数据库的 ClassNotFound 异常 class.forname("org.h2.Driver")【英文标题】:ClassNotFound exception for h2 database class.forname("org.h2.Driver") 【发布时间】:2016-02-28 20:22:52 【问题描述】:

我无法获取 Class.forname("org.h2.Driver");不抛出异常。我将 h2*.jar 添加到构建文件中,我什至得到了一个主文件来访问数据库(寒冷将在问题代码下。我正在尝试在 Vaadin 应用程序中使用 dbValues,但它只是不接受。我似乎无法导入任何包 org.h2.samples; 或 org.h2.*;

注意:dbValues 通过 Vaadin 项目运行。我不知道这是否有帮助,但这是我能想到的它(不起作用)和 dbTest(起作用)之间的唯一显着区别。

package com.example.assignment3;

import java.sql.*;
import java.util.ArrayList;

public class dbValues 

    ArrayList<business> a = new ArrayList<business>();

    public dbValues()
        
        business b = new business();
        ArrayList<business> a = new ArrayList<business>();
        
        try 
            Class.forName("org.h2.Driver");
         catch (ClassNotFoundException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        try 
            
            Connection conn = DriverManager.getConnection("jdbc:h2:~/test","Lucas","");
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT * FROM COMPANIES");
            while(rs.next())
                b.setID(rs.getInt("ID"));
                b.setName(rs.getString("NAME"));
                b.setSector(rs.getString("SECTOR"));
                b.setAddress(rs.getString("ADDRESS"));
                b.setProvince(rs.getString("PROVINCE"));
                a.add(b);
            
         catch (SQLException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        
    
    
    public ArrayList<business> returnBusinesses()
        return a;
    

这是似乎有效的代码。这两个在同一个目录中,所以这不是问题。

import java.sql.*;
import java.util.ArrayList;

import com.example.assignment3.business;
public class dbtest 
public static void main(String[] a)
throws Exception 

    /**
     * Create variables to iterate through when adding to database.
     */
    String dbname = "COMPANIES";
    int id = 0;
    String name = "";
    String sector = "";
    String address = "";
    String province = "";
    String query = "";
    
    Class.forName("org.h2.Driver");
    Connection conn = DriverManager.getConnection("jdbc:h2:~/test","Lucas","");
    
    /**
     * Create the business objects.
     */
    business boeing = new business(900162738, "Boeing Canada", "Aerospace", "123 Planes St.", "BC");
    business odysseyMoon = new business(900687789, "Odyssey Moon", "Aerospace", "687 The Moon", "NS");
    business vantage = new business(900278382, "Vantage Airport Group", "Aerospace", "77 Smith St.", "NB");
    business canadaBank = new business(900789213, "Bank of Canada", "Financial Services", "2325 Canada blvd.", "ON");
    business montrealBank = new business(900890876, "Bank of Montreal", "Financial Services", "2132 Bonjour Rd.", "QC");
    business rbc = new business(900564738, "Royal Bank of Canada", "Financial Services", "132 Clifton St.", "NB");
    business ubisoft = new business(900547967, "Ubisoft Halifax", "Interactive Media", "2000 Barrington St.", "NS");
    business scotiaBank = new business(900345273, "Scotia Bank", "Financial Services", "Yahmon Rd.", "NS");
    business propaganda = new business(900101928, "Propaganda Games", "Interactive Media", "25 Queen St.", "NT");
    business ea = new business(900162739, "EA Montreal", "Interactive Media", "54 Gagnon St.", "QC");
    
    /**
     * Create the arraylist that will be iterated through when adding
     * to the database and then add them to that list.
     */
    ArrayList<business> businesses = new ArrayList<business>();
    businesses.add(boeing);
    businesses.add(odysseyMoon);
    businesses.add(vantage);
    businesses.add(canadaBank);
    businesses.add(montrealBank);
    businesses.add(rbc);
    businesses.add(ubisoft);
    businesses.add(scotiaBank);
    businesses.add(propaganda);
    businesses.add(ea);
    
    /**
     * Perform the statement that populates the database.
     */
    try 
        Statement stmt = conn.createStatement();
        for(int i = 0; i < businesses.size(); i++)
            id = businesses.get(i).getID();
            name = businesses.get(i).getName();
            sector = businesses.get(i).getSector();
            address = businesses.get(i).getAddress();
            province = businesses.get(i).getProvince();
            query = "INSERT INTO " + dbname + " VALUES("+ id +", '"+ name +"', '"+ sector +"', '"+ address +"', '"+ province +"');";
            System.out.println(query);
            stmt.execute(query);
        
        //stmt.execute("DELETE FROM COMPANIES;");

     catch (SQLException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    


那么对这些问题有什么想法吗?我有大约 24 小时的时间来完成这项工作。

【问题讨论】:

【参考方案1】:

确保库位于类路径中。 您可以手动将库包含在 WEB-INF/lib 上。或者,您可以将 H2 jar 包含在 Tomcat 公用 lib 文件夹中。

【讨论】:

【参考方案2】:

JDBC 驱动程序以需要放置在 Servlet 容器而不是特定的 Web 应用程序中而闻名(臭名昭著?)。这避免了各种问题。正如this Answer by Reichart 解释的那样:

JDBC 驱动程序在所有 Web 应用程序共享的 JVM 范围的单例 DriverManager 中注册自己。

不幸的是,将您的 JDBC 驱动程序移至 Servlet 容器意味着您在该容器上的所有 Web 应用程序必须使用相同版本的驱动程序,也许还有数据库。

尚不确定这对 H2 意味着什么。但似乎最好将整个 H2 jar 放入 Servlet 容器而不是您的 Web 应用程序。

【讨论】:

以上是关于h2 数据库的 ClassNotFound 异常 class.forname("org.h2.Driver")的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 DataflowRunner 时出现 ClassNotFound 异常

Faces Servlet - ClassNotFound 异常 [重复]

Apache Oozie 在创建 mysql DB 时抛出 classnotfound 异常

H2数据库用户定义的java函数类未找到

spring boot中ConditionalOnClass为什么没有classNotFound类加载异常

如何在没有 ClassNotFound 异常的情况下在 Apache Tomcat 中配置 Impala/Hive2 JDBC 驱动程序