papin97
papin97

Reputation: 11

Crash when opening connection to Microsoft SQL with Glassfish

I am developing JavaEE 8 app with GlassFish 5.0.0 and I want to access database that resides in Microsoft SQL server. I attached Microsoft SQL driver 7.0 jre8 in Maven.

When I deploy the app and try to open a page which accesses the database, I got a crash. StackTrace below.

java.lang.NoSuchMethodError: sun.security.internal.spec.TlsMasterSecretParameterSpec.getExtendedMasterSecretSessionHash()[B
at com.sun.crypto.provider.TlsMasterSecretGenerator.engineGenerateKey(TlsMasterSecretGenerator.java:107)
at javax.crypto.KeyGenerator.generateKey(KeyGenerator.java:546)
at sun.security.ssl.Handshaker.calculateMasterSecret(Handshaker.java:1174)
at sun.security.ssl.Handshaker.calculateKeys(Handshaker.java:1120)
at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1126)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:351)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:984)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:919)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1756)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2391)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:2042)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:1889)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1120)
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:700)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at datas.DatabaseDatas.getLelang(DatabaseDatas.java:19)
at org.apache.jsp.company.halaman_005futama_005fcompany_jsp._jspService(halaman_005futama_005fcompany_jsp.java:595)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:411)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:473)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:377)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1580)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:258)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:652)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:591)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:463)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:168)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:242)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
at java.lang.Thread.run(Thread.java:748)

The code that triggers the crash is here:

public class DatabaseDatas {
private final static String sqlconn = "jdbc:sqlserver://<redacted>;" +
        "databaseName=dbName";

/**
 * Gets Lelang data in LelangList
 * @return Data in LelangList table
 */
public static ResultSet getLelang(){
    try {
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        Connection sqlconnection = DriverManager.getConnection(sqlconn,"sa","password"); //this is the one which trigger the crash
        sqlconnection.isValid(0); //ignore this
        Statement sta = sqlconnection.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
        String sql = "SELECT * FROM ListLelang";
        return sta.executeQuery(sql);
    } catch (ClassNotFoundException|SQLException e) {
        e.printStackTrace();
    }
    return null;
}

I use Jetbrains Intellij IDEA 2018.2.3 as IDE and set JDK 1.8.0_151 as Project SDK. I've also set javax.sql.DataSource and java.sql.driver in JDBC Connection Pool in GlassFish 5 Admin panel.

I have no idea why this happens. I can't find my error anywhere on the Internet. Please help me resolve this problem. I can provide more info if needed (as long as it's not personal info). Thank you.

EDIT: Actually I forget to test the connection pool. After I try to 'ping' via Glassfish 5 Admin Panel, I got the same error as the one in the stacktrace above. Glassfish admin panel error when pinging to MSSQL connection

Upvotes: 1

Views: 322

Answers (2)

papin97
papin97

Reputation: 11

I decided to ditch Glassfish completely (because as far as I see, Glassfish is quite out of date at the time of this writing) and using Apache TomEE (webservice version) as a web servlet.

And it works just fine, even with latest JDK (1.8.0_181)! No more errors regarding MSSQL anymore.

Upvotes: 0

rieckpil
rieckpil

Reputation: 12041

With Java EE you shouldn't open the database connection to your SQL-Server manually with the DriverManager. The application server (Glassfish) in your case is responsible for opening the connections and pooling them.

As you said you already configured Glassfish for the DataSource and the JDBC Connection Pool you won't need to do this in your code again. You can now use the DataSource with injecting it via @Resource(lookup="JNDI_NAME_OF_YOUR_DATASOURCE") DataSource dataSource; in your code (EJB or CDI) and work with it. You get the Connection with dataSource.getConnection();.

If you plan to use the EntityManager and work with JPA, you need a persistence.xml file in your application in the following directory: src/main/resources/META-INF and it could look like the following:

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
             version="2.2">
    <persistence-unit name="prod" transaction-type="JTA">
        <jta-data-source>JNDI_NAME_OF_YOUR_CONFIGURED_DATASOURCE</jta-data-source>
        <properties>
            <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
        </properties>
    </persistence-unit>
</persistence>

With this setup you can now inject the EntityManager in your CDI or EJB bean with @Resource EntityManager entityManager; and use it.

With this approach, you make sure that the application server is managing every infrastructure-related stuff (dealing with a database) and you can focus on your business logic.

The following tutorial might help you further: https://javaee.github.io/tutorial/resource-creation002.html

Upvotes: 1

Related Questions