Grails application response.outputStream << fails since upgrade to Grails 3.3 - spring

I have a Grails application that I have recently upgraded to 3.3 from 2.5. Generally things are working but today we ran across a problem that seems to be shared by others but I cannot find a solution.
In a controller I have a method that appends a string to the response.outputStream.
The code now appears as
response.status = OK.value()
response.contentType = 'text/csv;charset=UTF-8'
response.setHeader "Content-disposition", "attachment; filename=rcCandidate.csv"
response.outputStream << converted
response.outputStream.flush()
response.outputStream.close()
based on a suggestion found here
http://sergiodelamo.es/grails-tips-how-to-output-csv-from-a-grails-3-controller/
This code executes just fine on my test environment
$ grails -version
| Grails Version: 3.3.5
| Groovy Version: 2.4.15
| JVM Version: 1.8.0_162
but fails badly on the production server
$ java -version
java version "1.8.0_161"
Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)
$ apt list | grep tomcat
tomcat7/trusty-security,trusty-updates,now 7.0.52-1ubuntu0.13 all [installed]
The failures are reported starting with:
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: javax/servlet/WriteListener
followed by a stack trace, then this
Caused by: java.lang.NoClassDefFoundError: javax/servlet/WriteListener
then more stack trace and similar messages about WriteListener
I have seen suggestions to replace this line
provided "org.springframework.boot:spring-boot-starter-tomcat"
with
compile "org.springframework.boot:spring-boot-starter-tomcat"
But as pointed out here
https://docs.grails.org/latest/guide/deployment.html
that is not a good idea, and indeed when I tried it, tomcat did not start up.
I believe I've read somewhere that I might be able to cure this problem by replacing Tomcat7 with Tomcat8; however right now I'm running Ubuntu 14.04 on the server and Tomcat8 is not on offer in the repositories, so it's not quite straightforward to test that.
Does anyone have any suggestions for me? Thanks in advance.

You can fix this by adding #CompileStatic to your method, but that is not always feasible. We have fixed this problem in our applications by adding a static utility method:
#CompileStatic
public static sendResponseData(ServletOutputStream outputStream, String s) { // but this could be byte[] s or InputStream s or whatever you need
outputStream << s
}
and then calling that instead of the left shift operation.
You may need to add additional method signatures so that they can be statically compiled but the concept is the same. If I recall correctly, the left shift operator here uses some annotation or something (clearly I don't remember details!) that is not included by default (on Tomcat 7) but is also not needed.
Note that we also added
#CompileStatic
public static flushOutputStream(ServletOutputStream outputStream) {
outputStream.flush()
}
for convenience since that one has to be statically compiled as well.

Related

SpringBoot AutoConfigurationSorter 1.5.8 bug on Linux?

So I deployed a build that runs perfectly on my windows machine to a Linux box earlier this morning and when I tried to start the service I got the error below.
Caused by: java.lang.IllegalStateException: AutoConfigure cycle detected between org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration and org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
So I copied all of the libs from the target machine to my windows machine and ran the application from a windows command prompt. The application started fine.
So I eventually remote debugged the application and came up with a very interesting issue that has got my head scratching.
But before I went further I switched on -verbose to make sure the class in question was being loaded from the same jar in both windows and linux.
[Loaded org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration from file:/apps/IRDrsudbld/<project structure>/lib/spring-boot-autoconfigure-1.5.8.RELEASE.jar]
And it is.
So when I debug in linux and look at the metadata for the two classes
this = {AutoConfigurationSorter$AutoConfigurationClass#3645}
className = "org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration"
metadataReaderFactory = {ConcurrentReferenceCachingMetadataReaderFactory#3637}
autoConfigurationMetadata = {AutoConfigurationMetadataLoader$PropertiesAutoConfigurationMetadata#3611}
It states the following
"org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration.AutoConfigureBefore" -> "org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration"
"org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration.AutoConfigureAfter" -> "org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration"
But the line in bold is completely wrong as the 1.5.8 source code has the annotations below.
#Configuration
#ConditionalOnClass({CacheManager.class})
#ConditionalOnBean({CacheAspectSupport.class})
#ConditionalOnMissingBean(value = {CacheManager.class},name = {"cacheResolver"})
#EnableConfigurationProperties({CacheProperties.class})
#AutoConfigureBefore({HibernateJpaAutoConfiguration.class})
#AutoConfigureAfter({CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class,
RedisAutoConfiguration.class})
#Import({CacheAutoConfiguration.CacheConfigurationImportSelector.class})
public class CacheAutoConfiguration {
Has anyone seen an issue like this before as I am completely mystified as to what is happening here.
Thanks
After debugging the code it appears that one of the internal shaded jar files contains a spring-autoconfigure-metadata.properties which is for spring boot 2. When the application is executed on linux this jar file is loaded after the spring boot autoconfigure one and replaces the
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration.AutoConfigureAfter
Property with one that is not valid for the spring boot version in my application.
At least I have found out what the problem is.

Starting a payara 5 has encountered

I have build a very simple project of hello world in
Payara 5 (5.181)
JSF 2.3
JDK 1.8
CDI 2.0
Maven
and encountered a problem
Unable to start server due following issues: Launch process failed with exit code 1
in console it throws an error of :
Error: Could not find or load main class server\payara5\glassfish.lib.grizzly-npn-bootstrap.jar
[PIC] Payara 5 Error
It seems that the Payara Tools for Eclipse suffer by several bugs that may cause this. In my case, the following workarounds helped:
The Payara installation path should not contain spaces (e.g. Program Files\Payara)
It seems that only Java 8 is supported at the time
Open the domain.xml configuration file for the domain you are trying to start (typically payara_install_path/glassfish/domains/domain1/config/domain1.xml) and search for "Xbootclasspath". You should find a couple of lines like
<jvm-options>[1.8.0|1.8.0u120]-Xbootclasspath/p:${com.sun.aas.installRoot}/lib/grizzly-npn-bootstrap-1.6.jar</jvm-options>
<jvm-options>[1.8.0u121|1.8.0u160]-Xbootclasspath/p:${com.sun.aas.installRoot}/lib/grizzly-npn-bootstrap-1.7.jar</jvm-options>
<jvm-options>[1.8.0u161|1.8.0u190]-Xbootclasspath/p:${com.sun.aas.installRoot}/lib/grizzly-npn-bootstrap-1.8.jar</jvm-options>
<jvm-options>[1.8.0u191|1.8.0u500]-Xbootclasspath/p:${com.sun.aas.installRoot}/lib/grizzly-npn-bootstrap-1.8.1.jar</jvm-options>
Depending of your installed Java version (try running java --version) and choose the appropriate line (most likely the last one). Remove the remaining lines and remove the [...] part at the beginning of the chosen line so you will get something like
<jvm-options>-Xbootclasspath/p:${com.sun.aas.installRoot}/lib/grizzly-npn-bootstrap-1.8.1.jar</jvm-options>
After this, the tools seem to start normally.
The Problem is with Java version. The grizzly-npn-bootstrap-1.8.1.jar Jar is placed in bootclasspath, thats why it requires proper java version to start payara server. So remove unnecessary bootstrap jar from domain.xml.
In Windows:
1) Go To ---C:\Users\xxxx\payara5\glassfish\domains\domain1\config\domain.xml
2) According to my java verson(java version "1.8.0_191") I deleted the following lines from domain.xml. So delete according to your java version.
<jvm-options>[1.8.0|1.8.0u120]-Xbootclasspath/p:${com.sun.aas.installRoot}/lib/grizzly-npn-bootstrap-1.6.jar</jvm-options>
<jvm-options>[1.8.0u121|1.8.0u160]-Xbootclasspath/p:${com.sun.aas.installRoot}/lib/grizzly-npn-bootstrap-1.7.jar</jvm-options>
<jvm-options>[1.8.0u161|1.8.0u190]-Xbootclasspath/p:${com.sun.aas.installRoot}/lib/grizzly-npn-bootstrap-1.8.jar</jvm-options>
3) Remove this [1.8.0u191|1.8.0u500] part from jvm-options & Edit the line in your domain.xml(w.r.t java -version) as shown below
<jvm-options>-Xbootclasspath/p:${com.sun.aas.installRoot}/lib/grizzly-npn-bootstrap-1.8.1.jar</jvm-options>
4) restart your server.
As Radkovo said, "The Payara installation path should not contain spaces (e.g. Program Files\Payara)", so I moved the Payara to the Documents folder.
Problem solved!

Too small initial heap error - stanford parser

I am trying my hands on the Stanford dependency parser. I tried running the parser from command line on windows to extract the dependencies using this command:
java -mx100m -cp "stanford-parser.jar" edu.stanford.nlp.trees.EnglishGrammaticalStructure -sentFile english-onesent.txt -collapsedTree -CCprocessed -parserFile englishPCFG.ser.gz
I am getting the following error:
Error occurred during initialization of VM
Too small initial heap
I changed the memory size to -mx1024, -mx2048 as well as -mx4096. It didn't change anything and the error persists.
What am I missing?
Type -Xmx1024m instead of -mx1024.
See https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html
It should be -mx1024m. I skipped m.
One more thing: in the -cp, the model jar should also be included.
... -cp "stanford-parser.jar;stanford-parser-3.5.2-models.jar"...
(assuming you are using the latest version).
Otherwise an IO Exception will be thrown.
There may be some arguments that are preexisting in the IDE.
In eclipse:
Go to-> Run as-> run configuration-> Arguments
then Delete the arguments that are used previously.
Restart your eclipse.
Worked for me!

JDBC type-2 behavior with multiple DB2 Client versions installed

Our J2EE based application is run on Websphere Applicaiton Server- AIX server with 2 versions of DB2 Client installed (Db2v9.5, Db2v9.7).
I have a db SAMPLE which is remotely cataloged in both the two DB2 client versions with the same alias name SAMPLE.
If I uncatalog the DB from DB2v9.5 , the application goes down. However if I drop it from DB2v9.7 client the application is not impacted.
From this above test , we understand that some how DB2v9.5 is being used by default.
My objective now is to make the SAMPLE be pointed to only DB2v9.7 and the App must work without the sample DB in DB2v9.5.
Any suggestions on how to do it ?
The JDBC string used is "jdbc:db2:sample" (Note: there is no port for DB2 Client)
I have already tried to point $LIBPATH & $LD_LIBRARY_PATH to DB2v9.7 native lib32 path,
and also pointed the AIX user ID's .profile to DB2v9.7/sqllib/db2profile ,But no luck.
Regards,
Chandru
You have to check the default environment where Java is running, you will detect which Client is using. You could do that by executing "env" via Runtime, and see the defaults.
For example, with a small app like this:
import java.lang.*;
import java.io.*;
public class Test {
public static void main (String[] args) throws Exception {
Process p = Runtime.getRuntime().exec("env");
String line;
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
System.out.println("library " + System.getProperty("java.library.path"));
}
}
You call it with the same parameters you call your other application (JDBC driver included), and then check the output.
java <your params, classpath to db2java.zip> Test
Check the parameters like DB2INSTANCE, PATH, CLASSPATH.
More information in http://www.ibm.com/developerworks/data/library/techarticle/dm-0512kokkat/
List the files in /usr/lib and /usr/include. Do you see any file that points to DB2?
ls -l /usr/lib
ls -l /usr/include
Probably, you executed a db2ln, and that created links to a specific DB2 Client (9.5). Each time you execute the Java application, the LIBPATH takes precedence over /usr/lib, than the specified DB2 version
LIBPATH=/usr/lib:/lib:/opt/IBM/db2/V9.7/lib32
You can run the db2rmln command to remove the links.
Take a look at this page: http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/topic/com.ibm.db2.luw.qb.server.doc/doc/t0006747.html
This issue was resolved by completely killing all the JVM that is running from the same version and path of java and starting them back. (In our case an AIX JVM pConsole was running behind even after putting Dmgr,Node & CL down. Both pConsole and WAS uses the same java)
That was the reason that the updated shared native libraries didn't reflect in the WAS. But after killing&starting back each instance of java, including the ones apart from WAS the native libraries got reflected in the logs .
Sorry about updating the answer after so long.

jdk 1.7.25 CORBA idl build warning: Anonymous sequences and array are deprecated

My java project updated to jdk 1.7.25, over Solaris 10 environment, this is the first time seen that there is a new warning message in build log: Anonymous sequences and array are deprecated (build IDL)
problem: The main GUI(build by jdk 1.7.25) cannot been brought up
We think this maybe a problem(but not sure). The idl file is very simple:
$ cat UnsubscribeAttb.idl
//../../../proj/request/requestIfc/UnsubscribeAttb.idl
include ../../../proj/request/requestIfc/subscribeKey.idl
module requestIfc {
struct requestIfc {
bool subscribeKeys;
sequence<subscribeKey> UnsubscribeAttbList;
}
}
I put in "typedef" at the front of the last line, but build immediately gives an error complained this line, but didnot give me a specific reason. Looking for your help.
Thanks,
Curtis

Resources