problems creating object from YAML file - snakeyaml

I'm simply trying to manually read a dropwizard configuration file with SnakeYAML
My code looks like:
FileReader reader = new FileReader("/Users/novotny/IdeaProjects/fingage-platform/config-local.yml");
Yaml yaml = new Yaml();
FingageConfiguration config = yaml.loadAs(reader, FingageConfiguration.class);
System.err.println(config);
FingageConfiguration looks like:
public class FingageConfiguration extends Configuration {
#Valid
#NotNull
private String env;
#JsonProperty("env")
public String getEnv() {
return env;
}
And my config-local.yml looks like:
env: local
server:
requestLog:
timeZone: UTC
applicationConnectors:
- type: http
port: 9370
adminConnectors:
- type: http
port: 9371
I don't quite understand why Dropwizard has no difficulty in constructing an object, but I can't seem to do it with SnakeYAML or am I doing something wrong? I get the following error below:
Exception in thread "main" Cannot create property=server for JavaBean=FingageConfiguration{server=DefaultServerFactory{applicationConnectors=[io.dropwizard.jetty.HttpConnectorFactory#42d8062c], adminConnectors=[io.dropwizard.jetty.HttpConnectorFactory#6043cd28], adminMaxThreads=64, adminMinThreads=1, applicationContextPath=/, adminContextPath=/}, logging=DefaultLoggingFactory{level=INFO, loggers={}, appenders=[io.dropwizard.logging.ConsoleAppenderFactory#77f99a05]}}
in 'reader', line 1, column 1:
env: "local"
^
Unable to find property 'server' on class: com.fingage.FingageConfiguration
in 'reader', line 4, column 5:
requestLog:
^
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:308)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.construct(Constructor.java:189)
at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:341)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:182)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor.java:141)
at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:127)
at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:450)
at org.yaml.snakeyaml.Yaml.loadAs(Yaml.java:410)
at com.fingage.service.TestYaml.main(TestYaml.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: org.yaml.snakeyaml.error.YAMLException: Unable to find property 'server' on class: com.fingage.FingageConfiguration
at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:132)
at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:121)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.getProperty(Constructor.java:318)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:240)
... 13 more

As explained here problems may be caused by the absence of no arg constructors, setter/getter pairs or fields by themself. As soon as you adapt you classes to Java bean spec it works brilliantly.

As the stacktrace says, you are missing property FingageConfiguration.server. The messages above the stacktrace are just a mess.

Related

org.neo4j.ogm.context.GraphEntityMapper throwing IllegalArgumentException: Can not set Double field to java.math.BigDecimal

Upgraded existing API to use Neo4j 4.3.3 and neo4j-ogm-http-driver to 3.2.25. spring-boot-starter-data-neo4j is 2.3.4.Release. Now if I try to create/fetch a relationship with one of the attribute as Double using org.springframework.data.repository CrudRepository.save() and org.springframework.data.neo4j.repository Neo4jRepository.findById(), it throws below error:
Found relationship type: OWNS to map to RelationshipEntity: RelationshipEntityName
2021-08-21 00:25:14.780 ERROR 3556 --- [nio-8303-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Error mapping GraphModel; nested exception is org.neo4j.ogm.exception.core.MappingException: Error mapping GraphModel] with root cause
java.lang.IllegalArgumentException: Can not set java.lang.Double field RelationshipEntityName.percentage to java.math.BigDecimal
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
at java.lang.reflect.Field.set(Field.java:764)
at org.neo4j.ogm.metadata.FieldInfo.lambda$write$0(FieldInfo.java:352)
at java.security.AccessController.doPrivileged(Native Method)
at org.neo4j.ogm.metadata.FieldInfo.write(FieldInfo.java:349)
at org.neo4j.ogm.metadata.FieldInfo.write(FieldInfo.java:383)
at org.neo4j.ogm.context.GraphEntityMapper.writeProperty(GraphEntityMapper.java:305)
at org.neo4j.ogm.context.GraphEntityMapper.setProperties(GraphEntityMapper.java:268)
at org.neo4j.ogm.context.GraphEntityMapper.createRelationshipEntity(GraphEntityMapper.java:409)
at org.neo4j.ogm.context.GraphEntityMapper.mapRelationshipEntity(GraphEntityMapper.java:354)
at org.neo4j.ogm.context.GraphEntityMapper.mapRelationships(GraphEntityMapper.java:330)
at org.neo4j.ogm.context.GraphEntityMapper.mapContentOf(GraphEntityMapper.java:158)
at org.neo4j.ogm.context.GraphEntityMapper.lambda$map$2(GraphEntityMapper.java:115)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:117)
at org.neo4j.ogm.context.GraphRowModelMapper.map(GraphRowModelMapper.java:60)
at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.lambda$executeAndMap$1(ExecuteQueriesDelegate.java:165)
at org.neo4j.ogm.session.Neo4jSession.doInTransaction(Neo4jSession.java:590)
at org.neo4j.ogm.session.Neo4jSession.doInTransaction(Neo4jSession.java:564)
at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.executeAndMap(ExecuteQueriesDelegate.java:150)
at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.query(ExecuteQueriesDelegate.java:117)
at org.neo4j.ogm.session.Neo4jSession.query(Neo4jSession.java:425)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)
at org.springframework.data.neo4j.transaction.SharedSessionCreator$SharedSessionInvocationHandler.lambda$invoke$1(SharedSessionCreator.java:121)
at org.springframework.data.neo4j.transaction.SharedSessionCreator$SharedSessionInvocationHandler.invokeInTransaction(SharedSessionCreator.java:159)
at org.springframework.data.neo4j.transaction.SharedSessionCreator$SharedSessionInvocationHandler.invoke(SharedSessionCreator.java:123)
at com.sun.proxy.$Proxy88.query(Unknown Source)
at org.springframework.data.neo4j.repository.query.GraphQueryExecution$SingleEntityExecution.execute(GraphQueryExecution.java:64)
at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.doExecute(GraphRepositoryQuery.java:76)
at org.springframework.data.neo4j.repository.query.AbstractGraphRepositoryQuery.execute(AbstractGraphRepositoryQuery.java:57)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor$QueryMethodInvoker.invoke(QueryExecutorMethodInterceptor.java:195)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:152)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy111.findByResource(Unknown Source)
I tried changing the attribute percentage to Number, that does not throw the exception but percentage doesn't get saved.
I do not want to upgrade spring-boot-starter-data-neo4j to any major version at this point.
Upgrading to Spring-Data-Neo4j 6.x will again be big migration effort.
I am stuck now.
I found out the exact place where the error was coming from was neo4j.ogm.core files, I tried various versions of the jar but nothing worked.
Finally I resolved the problem by writing a custom converter as the implicit converter was not able to convert between Double and BigDecimal.
public class PercentageConverter implements AttributeConverter<Double, BigDecimal> {
#Override
public BigDecimal toGraphProperty(Double value) {
if (value == null) {
return null;
}
return new BigDecimal(value);
}
#Override
public Double toEntityAttribute(BigDecimal value) {
return value.doubleValue();
}
}
and annotate the entity attribute to use this converter
#Convert(PercentageConverter.class)
This resolved my error and now I can do all CRUD operations successfully

Unable to execute any StrutsTestCase using Struts2-Junit-Plugin, action method is null

First of all sorry if I don't explain it clearly enough, I will try to do my best. Recently I switched from C/C# to Java, and I'm a bit overwhelmed.
I'm working on a project that is using Struts2+Hibernate (I'm not using Spring); the idea was to use the struts2-JUnit-plugin to test the actions.
I followed the strut2-junit-plugin tutorial without success and after a lot of research and trying all the possible solutions posted everywhere I couldn't find the good one.
The "issues" (because I'm not really sure whether this is an issue or not...) I have is that when I try to run a StrutsTestCase, during the setUp:
super.setUp();
initServletMockObjects();
setupBeforeInitDispatcher();
dispatcher = initDispatcher(dispatcherInitParams);
setupAfterInitDispatcher(dispatcher);
When calling dispatcher = initDispatcher(dispatcherInitParams), dispatcherInitParams is null and it throws the following stack trace:
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
ERROR CdiObjectFactory [findBeanManager]: Could not find BeanManager instance for any given JNDI key, giving up
ERROR CdiObjectFactory Struts2 CDI integration could not be initialized.
ERROR DefaultConversionPropertiesProcessor Conversion registration error
java.lang.NullPointerException
at org.apache.struts2.cdi.CdiObjectFactory.getInjectionTarget(CdiObjectFactory.java:175)
at org.apache.struts2.cdi.CdiObjectFactory.buildBean(CdiObjectFactory.java:148)
at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:177)
at com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator.createTypeConverter(DefaultTypeConverterCreator.java:40)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.loadConversionProperties(DefaultConversionPropertiesProcessor.java:86)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.processRequired(DefaultConversionPropertiesProcessor.java:68)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.init(DefaultConversionPropertiesProcessor.java:59)
at com.opensymphony.xwork2.inject.InitializableFactory.create(InitializableFactory.java:45)
at com.opensymphony.xwork2.inject.Scope$2$1.create(Scope.java:52)
at com.opensymphony.xwork2.inject.ContainerBuilder$3.create(ContainerBuilder.java:118)
at com.opensymphony.xwork2.inject.ContainerBuilder$8.call(ContainerBuilder.java:626)
at com.opensymphony.xwork2.inject.ContainerBuilder$8.call(ContainerBuilder.java:623)
at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:555)
at com.opensymphony.xwork2.inject.ContainerBuilder.create(ContainerBuilder.java:623)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:187)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66)
at org.apache.struts2.dispatcher.Dispatcher.getContainer(Dispatcher.java:957)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:463)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:496)
at org.apache.struts2.util.StrutsTestCaseHelper.initDispatcher(StrutsTestCaseHelper.java:44)
at org.apache.struts2.StrutsTestCase.initDispatcher(StrutsTestCase.java:236)
at org.apache.struts2.StrutsTestCase.setUp(StrutsTestCase.java:216)
at com.xxxx.xxxxx.xx.xxx.PasswordActionTest.setUp(PasswordActionTest.java:31)
at junit.framework.TestCase.runBare(TestCase.java:139)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
ERROR DefaultConversionPropertiesProcessor Conversion registration error
java.lang.NullPointerException
at org.apache.struts2.cdi.CdiObjectFactory.getInjectionTarget(CdiObjectFactory.java:175)
at org.apache.struts2.cdi.CdiObjectFactory.buildBean(CdiObjectFactory.java:148)
at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:177)
at com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator.createTypeConverter(DefaultTypeConverterCreator.java:40)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.loadConversionProperties(DefaultConversionPropertiesProcessor.java:86)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.process(DefaultConversionPropertiesProcessor.java:64)
at com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor.init(DefaultConversionPropertiesProcessor.java:60)
at com.opensymphony.xwork2.inject.InitializableFactory.create(InitializableFactory.java:45)
at com.opensymphony.xwork2.inject.Scope$2$1.create(Scope.java:52)
at com.opensymphony.xwork2.inject.ContainerBuilder$3.create(ContainerBuilder.java:118)
at com.opensymphony.xwork2.inject.ContainerBuilder$8.call(ContainerBuilder.java:626)
at com.opensymphony.xwork2.inject.ContainerBuilder$8.call(ContainerBuilder.java:623)
at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:555)
at com.opensymphony.xwork2.inject.ContainerBuilder.create(ContainerBuilder.java:623)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:187)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66)
at org.apache.struts2.dispatcher.Dispatcher.getContainer(Dispatcher.java:957)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:463)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:496)
at org.apache.struts2.util.StrutsTestCaseHelper.initDispatcher(StrutsTestCaseHelper.java:44)
at org.apache.struts2.StrutsTestCase.initDispatcher(StrutsTestCase.java:236)
at org.apache.struts2.StrutsTestCase.setUp(StrutsTestCase.java:216)
at com.xxx.xxxx.xxx.xxxx.PasswordActionTest.setUp(PasswordActionTest.java:31)
at junit.framework.TestCase.runBare(TestCase.java:139)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
After this, even that I got the error, I can continue testing, for instance, the following test:
#Test
public void testGetActionProxy() throws Exception {
//set parameters before calling getActionProxy
PasswordUpdate pu = new PasswordUpdate();
pu.setCurrentPassword("current");
pu.setNewPassword("new");
pu.setNewPasswordConfirm("new");
request.setParameter("passwordUpdate.currentPassword", pu.getCurrentPassword());
request.setParameter("passwordUpdate.newPassword", pu.getNewPassword());
request.setParameter("passwordUpdate.newPasswordConfirm", pu.getNewPasswordConfirm());
ActionProxy proxy = getActionProxy("/UpdatePassword.action");
assertNotNull(proxy);
PasswordAction action = (PasswordAction) proxy.getAction();
assertNotNull(action);
String result = proxy.execute();
assertEquals(Action.SUCCESS, result);
assertNotNull(action.getPasswordUpdate());
assertEquals("current", action.getPasswordUpdate().getCurrentPassword());
assertEquals("new", action.getPasswordUpdate().getNewPassword());
assertEquals("new", action.getPasswordUpdate().getNewPasswordConfirm());
}
The second issue is that it doesn't seem to find the action when calling:
ActionProxy proxy = getActionProxy("/UpdatePassword.action");
It's throwing an exception inside getActionProxy:
protected ActionProxy getActionProxy(String uri) {
request.setRequestURI(uri);
ActionMapping mapping = getActionMapping(request);
String namespace = mapping.getNamespace();
String name = mapping.getName();
String method = mapping.getMethod();
Configuration config = configurationManager.getConfiguration();
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, method, new HashMap<String, Object>(), true, false);
initActionContext(proxy.getInvocation().getInvocationContext());
// this is normally done in onSetUp(), but we are using Struts internal
// objects (proxy and action invocation)
// so we have to hack around so it works
ServletActionContext.setServletContext(servletContext);
ServletActionContext.setRequest(request);
ServletActionContext.setResponse(response);
return proxy;
}
At this point String method is null and the following call is throwing an exception:
ActionProxy proxy =
config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, method, new HashMap(), true, false);
Any idea before I give up?
Thank you!
In case someone else ends up in this post with the same issue
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
ERROR CdiObjectFactory [findBeanManager]: Could not find BeanManager instance for any given JNDI key, giving up
ERROR CdiObjectFactory Struts2 CDI integration could not be initialized.
ERROR DefaultConversionPropertiesProcessor Conversion registration error
You can fix this by excluding from your configuration struts2-cdi-plugin

Grails Service can't create Sql instance

How can I create an instance of class groovy.sql.Sql in a Grails service without using dataSource or anything GORM Hibernate related? In my Grails app, in my Service class when I try to create a Sql instance I get an exception:
Caused by: java.lang.ClassNotFoundException: org.postgresql.Driver
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java_lang_ClassLoader$loadClass$1.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at com.tav.admin.DbService.copyFileToTable(DbService.groovy:87)
Seems to be a class loading issue. Here is the service method.
long copyFileToTable(String sql, FileReader fileReader) {
println("System Class Loader: ${ClassLoader.getSystemClassLoader().getClass().getName()}")
println("Groovy Class Loader: ${Thread.currentThread().getContextClassLoader().getClass().getName()}")
Thread.currentThread().getContextClassLoader().loadClass(driverClassName)
ClassLoader.getSystemClassLoader().loadClass(driverClassName) // Note throws exception here!
props = new Properties()
props.setProperty('user', username)
props.setProperty('password', password)
PgConnection copyOperationConnection = (PgConnection) Sql.newInstance(url, props, driverClassName)
CopyManager copyManager = new CopyManager(copyOperationConnection)
return copyManager.copyIn(sql, fileReader)
}
Output:
System Class Loader: sun.misc.Launcher$AppClassLoader
Groovy Class Loader: groovy.lang.GroovyClassLoader
The PostgreSQL driver is registered with DriverManager. I can use the injected dataSource in my service but I need to create and new connection to the database unrelated to GORM Hibernate to use driver specific functionality (PostgreSQL CopyManager).
In DriverManager.isDriverAllowed()
Class.forName(driver.getClass().getName(), true, classLoader);
return null.
Version info: Grails 2.5.1, Java jdk1.7.0_79, Groovy 2.0.6
I have narrowed the problem down to the line of code below:
ClassLoader.getSystemClassLoader().loadClass(driverClassName) // Note throws exception here!
Seems like Groovy/Grails loads the JDBC driver using the GroovyClassLoader but when you try to get a connection from DriverManager.getConnection(), driver manager tries to load the JDBC driver using the System Class Loader. The system class loader seems unaware that the Groovy class loader has already loaded the class. It's like the DriverManager and the System Class loader are sandboxed away from the Groovy loaded classes.
In my case I have the same situation (use Sql without GORM) but with MySQL.
I declared a dataSource bean at resources.groovy :
beans{
"otherDataSource"(BasicDataSource) {
driverClassName = 'com.mysql.Driver'
username = 'xxx'
password = 'xxxx'
url = 'jdbc:blablabla'
}
}
And inject it at the service
class MyService{
def otherDataSource
void doIt(){
def sql = new Sql(otherDataSource)
}
}
In order to interface with PostgreSQL you need to have a suitable driver in the classpath as the stack trace says.
You need to have a dependency included or an external library bundled in a jar that will provide you with a package that implements the `javax.sql.*' interface.

Issues with Grails 3 domain class named "Application"

I have a legacy system that I am migrating to Grails 3 but I'm running into a naming convention issue. One of our tables is called Application but that is also the name of the Groovy class that runs the application. There seems to be an issue where GORM is confusing the 2 classes and giving type-casting errors. I have tried explicitly casting my Application class in my ApplicationDegree class to try and force GORM to recognize which class I am trying to use but no success.
I know an option is that I can rename my domain Application class to something else and manually map it to the appropriate database table but I want to avoid that as I foresee issues down the road.
So, other than renaming my Domain classes, how can I get Grails/GORM to make the correct mapping.
Grails 3.1.4
Code:
ApplicationDegree ad = ApplicationDegree.findById(10);
Class:
class ApplicationDegree {
Boolean isPrimary
domain.package.Application application
Degree degree
static hasMany = [applicationDegreeMajors: ApplicationDegreeMajor,
applicationDegreeMinors: ApplicationDegreeMinor]
static belongsTo = [domain.package.Application, Degree]
static mapping = {
version false
degree column: 'degree_code'
isPrimary column: 'isPrimary'
}
}
StackTrace:
ERROR org.grails.spring.beans.factory.OptimizedAutowireCapableBeanFactory - Bean couldn't be autowired using grails optimization: Property 'application' threw exception; nested exception is java.lang.IllegalArgumentException: argument type mismatch
ERROR org.grails.spring.beans.factory.OptimizedAutowireCapableBeanFactory - Retrying using spring autowire
ERROR org.grails.web.errors.GrailsExceptionResolver - IllegalStateException occurred when processing request: [GET] /app4grad_V2/college/applications/
Cannot convert value of type [app4grad.Application] to required type [domain.package.Application] for property 'application': no matching editors or conversion strategy found. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.InstantiationException: Could not instantiate entity: : domain.package.ApplicationDegree
at app4grad.college.ApplicationsController$$EPuFyMDe.index(ApplicationsController.groovy:14)
... 3 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
... 4 common frames omitted
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type [app4grad.Application] to required type [domain.package.Application] for property 'application'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [app4grad.Application] to required type [domain.package.Application] for property 'application': no matching editors or conversion strategy found
... 4 common frames omitted
Caused by: java.lang.IllegalStateException: Cannot convert value of type [app4grad.Application] to required type [domain.package.Application] for property 'application': no matching editors or conversion strategy found
... 4 common frames omitted
I had the same problem, the problem is that you're using a reserved name : https://grails.org/wiki/Reserved%20Names
Using Intelij Idea you can easily rename you're domain class and the IDE will do the rest for you.

IllegalArgument exception in custom setter after upgrading to JSF2

After upgrading to JSF2 (probably) one special accessor in an .xhtml file generates IllegalArgumentExceptions but I can't really find out why. Running the app on my local JBoss (4.2.2) does not generate this exception but this can be related to a difference between debug and live data.
Following stack trace is generated that I could extract from the production server log:
Caused by: javax.el.ELException: /xy/xy-subtemplate1.xhtml #131,45 value="#{someClass.someProperty}": java.lang.IllegalArgumentException
at com.sun.facelets.el.TagValueExpression.setValue(TagValueExpression.java:101)
at javax.faces.component.UIInput.updateModel(UIInput.java:818)
... 36 more
Caused by: java.lang.IllegalArgumentException
at sun.reflect.GeneratedMethodAccessor1134.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.el.BeanELResolver.setValue(BeanELResolver.java:108)
at com.sun.faces.el.DemuxCompositeELResolver._setValue(DemuxCompositeELResolver.java:255)
at com.sun.faces.el.DemuxCompositeELResolver.setValue(DemuxCompositeELResolver.java:281)
at org.apache.el.parser.AstValue.setValue(AstValue.java:114)
at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:249)
at com.sun.facelets.el.TagValueExpression.setValue(TagValueExpression.java:93)
... 37 more
someClass is being iterated over in a list and has the following methods to access someProperty:
public int getSomeProperty() {
return this.getSomeRelatedEnum().ordinal();
}
public void setSomeProperty( final int index) {
this.setSomeRelatedEnum( SomeRelatedEnum.fromOrdinal( index) );
}
How can this lead to the IllegalArgumentException mentioned above?
That can happen when the setter method after all expects a different argument type than the one which is provided from EL on.
I guess that it's related to the fact that hardcoded/unconverted numbers in EL are by default treated as long and not as int. Try either changing the int to be long, or providing an explicit integer converter on the input component like so <h:someInput converter="javax.faces.Integer">.
By the way, why don't you just get/set the enum itself directly? Getting/setting the enum by its ordinal is whacky.

Resources