glassfish icon indicating copy to clipboard operation
glassfish copied to clipboard

ClassNotFoundException: org.apache.derby.client.am.SqlException

Open hantsy opened this issue 3 years ago • 2 comments
trafficstars

Environment Details

  • GlassFish Version (and build number): 7.0.0-M9
  • JDK version: 17
  • OS: Windows 10 Pro
  • Database: Built-in Derby

The example project to reproduce, check JPQLFunctionsTest.

Testing the functions introduced in JPA 3.1 using jpql literal query, failed.

[ERROR] com.example.it.JPQLFunctionsTest.testExtractFunctions  Time elapsed: 0.164 s  <<< ERROR!
org.jboss.arquillian.test.spi.ArquillianProxyException: org.jboss.arquillian.junit5.IdentifiedTestException : null [Proxied because : Original exception caused: class java.lang.ClassNotFoundException: org.apache.derby.client.am.SqlException]
        at org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner$ArquillianTestMethodExecutionListener.getTestResult(JUnitJupiterTestRunner.java:101)
        at org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner$ArquillianTestMethodExecutionListener.access$100(JUnitJupiterTestRunner.java:69)
        at org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner.execute(JUnitJupiterTestRunner.java:58)
        at org.jboss.arquillian.protocol.servlet5.runner.ServletTestRunner.executeTest(ServletTestRunner.java:139)
        at org.jboss.arquillian.protocol.servlet5.runner.ServletTestRunner.execute(ServletTestRunner.java:117)
        at org.jboss.arquillian.protocol.servlet5.runner.ServletTestRunner.doGet(ServletTestRunner.java:86)
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527)
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
        at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1376)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:120)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:611)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:550)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:75)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:121)
        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:294)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:187)
        at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:440)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:144)
        at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:174)
        at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:153)
        at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:196)
        at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:88)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:246)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:178)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:118)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:96)
        at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:51)
        at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:510)
        at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:82)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:83)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:101)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:535)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:515)
        at java.base/java.lang.Thread.run(Thread.java:833)

hantsy avatar Oct 01 '22 01:10 hantsy

@ivargrimstad It seems the built-in derby driver is incompatible.

hantsy avatar Oct 01 '22 01:10 hantsy

I am not sure it is an EclipseLink bug or introduced in the GlassFish EclipseLink integration.

hantsy avatar Oct 01 '22 01:10 hantsy

Still failed in M10

hantsy avatar Nov 23 '22 14:11 hantsy

Hi @hantsy , can you please instruct how to execute the test? I tried it but it seems that the cargo plugin isn't used when I run mvn verify -Pglassfish. And when I run GlassFish manually, mvn verify -Pglassfish fails with an error in Arquillian.

OndroMih avatar Nov 26 '22 15:11 OndroMih

Try this https://github.com/hantsy/jakartaee10-sandbox/blob/master/.github/workflows/jpa.yml#L32 please.

The glassfish profile is to run with Cargo maven plugin.

hantsy avatar Nov 26 '22 16:11 hantsy

@hantsy I believe you have to use proper dependencies on the client side. Apply

diff --git a/jpa/pom.xml b/jpa/pom.xml
index 54e9335..ef0fc89 100644
--- a/jpa/pom.xml
+++ b/jpa/pom.xml
@@ -210,6 +210,11 @@ under the License.
                     <version>${arquillian-glassfish-jakarta.version}</version>
                     <scope>test</scope>
                 </dependency>
+                <dependency>
+                    <groupId>org.apache.derby</groupId>
+                    <artifactId>derbyclient</artifactId>
+                    <version>10.15.2.0</version>
+                </dependency>
             </dependencies>
             <build>
                 <testResources>

and you'll transit to

[ERROR] com.example.it.JPQLFunctionsTest.testExtractFunctions  Time elapsed: 0.381 s  <<< FAILURE!
org.opentest4j.AssertionFailedError
	at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:46)
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
...
Caused by: jakarta.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 4.0.0.v202210051929): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: 'WEEK' is not recognized as a function or procedure.
Error Code: 20000
Call: SELECT NAME, YEAR(BIRTHDATE), ((MONTH(BIRTHDATE)+2)/3), MONTH(BIRTHDATE), WEEK(BIRTHDATE), DAY(BIRTHDATE), HOUR(BIRTHDATE), MINUTE(BIRTHDATE), CAST(SECOND(BIRTHDATE) AS FLOAT) FROM PERSON
Query: ReportQuery(referenceClass=Person sql="SELECT NAME, YEAR(BIRTHDATE), ((MONTH(BIRTHDATE)+2)/3), MONTH(BIRTHDATE), WEEK(BIRTHDATE), DAY(BIRTHDATE), HOUR(BIRTHDATE), MINUTE(BIRTHDATE), CAST(SECOND(BIRTHDATE) AS FLOAT) FROM PERSON")
...

pzygielo avatar Nov 27 '22 10:11 pzygielo

So I guess, @pzygielo , the issue is that Derby doesn't support the WEEK function? I don't see the WEEK function in the docs: https://db.apache.org/derby/docs/10.16/ref/index.html while all others are there.

OndroMih avatar Nov 27 '22 10:11 OndroMih

IMO there is no issue in GF reported here, and this should be closed.

pzygielo avatar Nov 27 '22 11:11 pzygielo

Hi @hantsy , I agree with @pzygielo, this isn't an issue in GlassFish. It looks like Derby DB doesn't support the WEEK function. I recommend to either raise an issue for Derby to add support for the WEEK function or maybe for Eclipselink to somehow emulate the WEEK function for Derby if possible.

OndroMih avatar Nov 27 '22 11:11 OndroMih

@pzygielo The GlassFish includes derby distribution. This error was occurred since GlassFish M9. In before experience, when using the default Datasource, we do not need to add a Jdbc driver.

@OndroMih Although it is part of JPA 3.1, EclipseLink should provide it for all supported databases. If it is not a EclipseLink-Glassfish integration bug, it should be an issue from EclipseLink.

hantsy avatar Nov 27 '22 13:11 hantsy

This error was occurred since GlassFish M9.

With M8 I'm getting the same class java.lang.ClassNotFoundException: org.apache.derby.client.am.SqlException.

In before experience, when using the default Datasource, we do not need to add a Jdbc driver.

Please define before.

pzygielo avatar Nov 27 '22 14:11 pzygielo

@hantsy , what @pzygielo means it that the ClassNotFoundException happens on the Arquillian (test client) side, because GlassFish throws an exception of type org.apache.derby.client.am.SqlException, which Arquillian tries to serialize to the test client side, and that fails because that class is not available in your test client (JUnit classpath). The class is present in GlassFish, only when the error is transferred to JUnit you see the ClassNotFoundException.

The actual issue is that the SqlException is thrown in GlassFish, which is because Eclipselink generates an SQL that relies on the WEEK function and Derby doesn't support it. So either Derby needs to support it or Eclipselink needs to generate an SQL compatible with what Derby supports, if that's possible. There's no way GlassFish team can fix this other than replace Derby with some other embedded DB which supports the WEEK function.

OndroMih avatar Nov 27 '22 15:11 OndroMih

  • https://github.com/eclipse-ee4j/eclipselink/issues/1583

GF 7.0.0-M10 uses the latest 4.0.0 EL: https://github.com/eclipse-ee4j/glassfish/blob/a44106a9509a9076338b8e880c73b4d2d94b7bc0/appserver/pom.xml#L109

pzygielo avatar Nov 27 '22 15:11 pzygielo

@hantsy , what @pzygielo means it that the ClassNotFoundException happens on the Arquillian (test client) side, because GlassFish throws an exception of type org.apache.derby.client.am.SqlException, which Arquillian tries to serialize to the test client side, and that fails because that class is not available in your test client (JUnit classpath). The class is present in GlassFish, only when the error is transferred to JUnit you see the ClassNotFoundException.

@OndroMih In this JPQLFunctionTest, the tests does not work as CLIENT mode, so the test itself is like a CDI bean in test war archive deployed in the target server.

It dose not require a Derby client dependency in tests at all when using the default Datasource, it is similar to a simple Jakarta application which used the default DataSource and deployed to the GF/WildFly, no extra drivers required at all.

Unless GF itself lacks a Derbeyclient. But the test class also includes other tests which are successful, so it is not an issue of Derby driver, maybe an incompatible version between GF built-in and EclipseLink used for test against Derby, or Eclipselink used the DerbyClient but GF used a slim version when creating the default DataSource.

Thanks for your help.

hantsy avatar Nov 28 '22 02:11 hantsy

The actual issue is that the SqlException is thrown in GlassFish, which is because Eclipselink generates an SQL that relies on the WEEK function and Derby doesn't support it.

For Derby you can write function in Java, just FYI. https://db.apache.org/derby/docs/10.16/ref/rrefcreatefunctionstatement.html

dmatej avatar Nov 28 '22 09:11 dmatej

In this JPQLFunctionTest, the tests does not work as CLIENT mode, so the test itself is like a CDI bean in test war archive deployed in the target server.

And the test completes fine on the server-side. It's the problem with reporting the outcome in maven process.

It dose not require a Derby client dependency in tests at all when using the default Datasource, it is similar to a simple Jakarta application which used the default DataSource and deployed to the GF/WildFly, no extra drivers required at all.

No extra drivers required here as well. But this test is using more parts, not only GF and Derby. And the client-side CP is not prepared correctly for the exceptional flow.

Unless GF itself lacks a Derbeyclient.

No.

But the test class also includes other tests which are successful, so it is not an issue of Derby driver, maybe an incompatible version between GF built-in and EclipseLink used for test against Derby, or Eclipselink used the DerbyClient but GF used a slim version when creating the default DataSource.

No.

  1. What JVMs (more than 1) are participating in this test and what is the traffic that is exchanged between them?
  2. Is there CNFException for o.a.d.c.a.SqlException reported on the server-side? Contrary - it is in the middle of the logged stack trace as not causing any problem:
$ grep -A4 -B10 am.SqlExce jpa/target/glassfish7/glassfish/domains/domain1/logs/server.log
	at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:51)
	at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:510)
	at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:82)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:83)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:101)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:535)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:515)
	at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.sql.SQLSyntaxErrorException: 'WEEK' is not recognized as a function or procedure.
	at org.apache.derby.client.am.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:94)
	at org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:325)
	at org.apache.derby.client.am.ClientConnection.prepareStatement(ClientConnection.java:1479)
	at com.sun.gjc.spi.base.ConnectionHolder.prepareStatement(ConnectionHolder.java:575)
	at com.sun.gjc.spi.jdbc40.ConnectionWrapper40.prepareCachedStatement(ConnectionWrapper40.java:241)
	at com.sun.gjc.spi.jdbc40.ConnectionWrapper40.prepareCachedStatement(ConnectionWrapper40.java:39)
  1. What happens when EL is excluded from CP on client-side? (-Dmaven.test.dependency.excludes=org.eclipse.persistence:*). What is the exception reported then?

Hope that clarifies the case.


The issue in EL has been re-opened, so maybe there will be new version with the fix. If you want to track this dependency update in GF, please file new issue for that.

pzygielo avatar Nov 28 '22 14:11 pzygielo

Still failed in 7.0.0 GA.

hantsy avatar Jan 09 '23 10:01 hantsy

If you want to track this dependency update in GF, please file new issue for that.

pzygielo avatar Jan 09 '23 10:01 pzygielo

Please define before.

@pzygielo

Before Java EE 7, all datasources/drivers are registered in the admin console or admin command line provided application server. The application server can not recognized the drivers dependency in Java EE projects.

And since Java EE 7, it allows developers to add drivers to project dependencies, and register custom datasources via annotations.

When using the built-in datasource in GlassFish, the default datasource should be ready for developers. Please note, in JPA config, we use Datasource directly, not the drivers.

hantsy avatar Jan 09 '23 10:01 hantsy

First - EL has to be released with the fix. It's hard to upgrade earlier.

pzygielo avatar Jan 09 '23 10:01 pzygielo

When using the built-in datasource in GlassFish, the default datasource should be ready for developers.

It is.

Still failed in 7.0.0 GA.

The problem described is with dependencies on the client-side, that became visible due to SQL with WEEK.

This will not be resolved in GF in any way. Client shall be updated to get the exception about the WEEK.

pzygielo avatar Jan 09 '23 10:01 pzygielo