Using Grails 1.3.9
buildConfig.groovy
compile "org.grails.plugins:async-http-builder"
code:
AsyncHttpBuilder client = new AsyncHttpBuilder()
Promise<HttpClientResponse> p = client.post("http://someuUrl") {
contentType 'application/json'
json {
receiver number
message content
sender sender
}
}
p.onComplete { HttpClientResponse resp ->
println(resp);
}
I get the error in the topic title. What am I missing here?
A rather general steps for checking problems with missing plugins
Check if you have mavenRepo "https://repo.grails.org/grails/plugins" in repositories { in BuildConfig.groovy
Provide plugin version, so instead of "org.grails.plugins:async-http-builder" try "org.grails.plugins:async-http-builder:1.0.0"
Try grails refresh-dependencies in the terminal
Looking at the commit dates, it looks like a fresh plugin (<1 year old), so it's possible it works only with newer Grails versions (2+/3+).
The documentation states
Note that this client does not require Grails itself, and can easily be used standalone or as an independent HTTP client.
(...)
To get started with the HTTP client you should declare a dependency on the grails-http-client project in your build.gradle file:
compile "org.grails:http-client:VERSION"
So I would probably just try that, as the plugin might not play well with your old Grails version.
Related
I just installed Grails 3.3.0 and I'd like to configure some custom repositories in the ${HOME}/user/.grails/settings.groovy file.
This is what I've done so far (Real URLs have been replaced for <someUrl1|2>):
grails {
profiles {
repositories {
repo1 {
url = "<someUrl1>"
snapshotsEnabled = true
}
repo2 {
url = "<someUrl2>"
snapshotsEnabled = true
}
}
}
}
Now, when I execute grails command on bash (Ubutu 16.04) it always tries to resolve the dependencies from the first repository (<someUrl1>)
Java: jdk8u141
Should this configuration be done like I did?
If not, How could I configure this file in order to use more than one repo for grails?
If having connectivity issues (or whatsoever), the first attempt to connect to the first repository fails, Does Grails tray to access the other ones declared?
Should this configuration be done like I did?
Yes, according to the documentation
Does Grails tray to access the other ones declared?
Yes, the list of repositories are passed into the constructor of this class.
https://github.com/grails/grails-core/blob/master/grails-shell/src/main/groovy/org/grails/cli/profile/repository/MavenProfileRepository.groovy#L48
I'm trying to disable automatic reload/recompiling in Grails 3.1 as I would like to use JRebel instead.
I find springloaded rather limited, but more importantly is constantly fails with
File /Users/engrun/Development/projects/grailsPoc/grails-app/controllers/grailsPoc/HelloController.groovy changed, recompiling...
java.lang.IllegalAccessException: Class org.springsource.loaded.ReloadableType can not access a member of class org.springframework.aop.framework.CglibAopProxy$ClassLoaderAwareUndeclaredThrowableStrategy with modifiers "public"
I have tried all kinds of settings that I have found available, however, none actually disables reloading when running the run-app command
I have tried
disable.auto.recompile=true
on command line, GRAILS_OPTS, and in application.yml
I have tried the
-noreloading
flag, both on command line and GRAILS_OPTS.
According to docs, this should have worked
https://grails.org/wiki/Auto%20Reloading
And the answer accepted as the correct one here
how can I disable reloading in a grails 3.0.0 app?
does not work either.
Have anyone actually succeeded in disabling auto-reloading in Grails 3.1?
(And successfully configured Grails 3 with JRebel?)
In 3.x apps you can disable Spring Loaded by adding
grails {
agent {
enabled = false
}
}
to build.gradle.
Burt's answer is correct related to the question -> how to disable autoreloading.
However, Anton's answer is relevant to the second/related issue on getting Jrebel to work.
I now have a working example, which works with both
gradle bootRun -Pjrebel -> disable springloaded, using jrebel
gradle bootRun -> uses springloaded
and
grails
grails> run-app
My config is a combination of
export GRAILS_OPTS="-javaagent:$JREBEL_HOME/jrebel.jar -Drebel.base=/Users/<username>/.jrebel"
and build.gradle
rebel {
alwaysGenerate = false
showGenerated = true
//rebelXmlDirectory = "build/classes"
}
if (project.hasProperty('jrebel')) {
bootRun.dependsOn(generateRebel)
grails {
agent {
enabled = false
}
}
tasks.withType(JavaExec) {
jvmArgs "-javaagent:jrebel.jar"
jvmArgs "-Xverify:none"
}
}
Thanks #burt-beckwith and #anton-arhipov for your input!
To enable JRebel for Grails 3 project you need to configure -javaagent argument with the corresponding path the jrebel.jar in build.gradle file:
tasks.withType(JavaExec) { jvmArgs "-javaagent:jrebel.jar" }
I just grabbed the latest version of the functional testing plugin and it's focus, at least from the docs, has changed a bit. This is not a bad thing. The HtmlUnit integration is nice. But now, there isn't anything in the docs about RESTful testing of web services. However, what I used to do with functionaltestplugin.FunctionalTestCase still works, which is great.
For example:
void testCertifyEmployerCertifierNotFound() {
post('/employerCertification/certifyEmployer') {
headers['Content-Type'] = 'application/json'
body {
"""
{
'employerName': 'ACME',
'certifierExteralId': '1234556',
'certifyingUserId': '123445'
}
"""
}
}
assertStatus 200
assertContentType "application/json"
def model = this.response.contentAsString
def map = JSON.parse(model)
assertFalse(map.success)
assertNotNull(map.errorCode)
assertTrue(map.errorCode == EmployerCertificationService.ERROR_RESPONSE.CERTIFIER_NOT_FOUND.toString())
}
Is this plugin still the "defacto" plugin to use for functional web service testing and is my approach above still valid?
if your target is testing REST request/response I suggest you to use rest client builder plugin. You don't need complex browser-simul plugins. Use it is very simple in just two steps after installing it:
add event to manage functional tests in scripts/_Events.groovy: this is a system grail file used to hook some events at runtime. Just copy and paste this snippet:
eventAllTestsStart = {
if (getBinding().variables.containsKey("functionalTests")) {
functionalTests << "functional"
}
}
Now you can create functional tests in test/functional folder, rememeber to ends filename with Spec, grails will not find any tests if you forget this.
This is an example:
import grails.plugins.rest.client.RestBuilder
import spock.lang.Specification
class AuthenticationSpec extends Specification {
String baseUrl = "http://localhost:8080/grouply-backend"
void "test login wrong credentials"() {
given:
RestBuilder restBuilder = new RestBuilder()
when: "sending wrong credential"
def response = restBuilder.post("${baseUrl}/auth/login") {
json {
username = 'foo'
password = 'bar'
}
}
then: "authentication http error should happen"
response.status == 401
}
}
run tests with $ grails test-app functional:
I have just tried to use both functional testing plugin and webtest plugin with almost-current Grails 2.4.2 and I am sad to report that they are both borked. :(
Functional testing plugin has been practically abandoned for at least 9 months now. On December 2013 a critical bug that makes all of tests written using this plugin not working has been reported. There was no response from plugin developer regarding it up to the day I am writing this. And as this developer, Marc Palmer has switched to iOS development and consultancy in August 2014 I don't believe this bug will ever be resolved.
Webtest plugin has been last updated more than 3 years ago and it "requires Grails 1.2.RC2+". I run into ugly error of missing webtest.jar when running it and it looks like this plugin just haven't been updated to current Grails version. Also its syntax is not very Groovy-like and not nice.
Fortunately Geb integration for Grails plugin is supposed to work with current Grails versions. :) In fact in does only work with Grails 2.3.1+, as of writing these words has been last time updated in June 2014 and it's example tests project have been updated to Grails 2.4.3, release just a few days ago already, so it is very up-to-date. However I haven't used this project yet. Also looking at is's example code I am not sure it the best choice for RESTful API testing - it's more of a GUI web application testing tool..
Although is probably not very "grails style" i guess it should be possible to start up the whole stack with the spring context and run integration rest tests using apache HttpClient.
I have a Grails plugin that I've written that has its version set using set-version within our continuous integration environment. While building, I'd like to programmatically output the version from within "eventCompileEnd" event hook. So, for my Grails app I can just get the "app.version" metadata but plugin versions are set in the GrailsPlugin.groovy file in the root of the plugin. Is there any way to access that value? Here's the version info I'm referring to:
class MyUtilityGrailsPlugin {
// the plugin version
def version = "4.6.8"
// the version or versions of Grails the plugin is designed for
def grailsVersion = "2.1 > *"
...etc.
You can use below eventCompileEnd event in _Events.groovy of the app to get the name and version of all the plugins used in the app from GantBinding which is by default available to the post compile event. You can filter your plugin info based on the name:
//scripts/_Events.groovy
eventCompileEnd = {msg->
msg.supportedPluginInfos.each{println "${it.name} - ${it.version}"}
}
If you want to access the plugin info from any where else (for example: BootStrap) using applicationContext would be the simplest approach. Something like below would be useful:
//Bootstrap.groovy
def grailsApplication
def init = { servletContext ->
grailsApplication.mainContext.getBean('pluginManager')
.allPlugins.each{plugin->
println "Plugin Info ${plugin.name} - ${plugin.version}"
}
}
In your case, appCtx will not be available in post compile event, so you have to depend on GantBinding.
I found that version information can be retrieved from within an event hook for that plugin by doing this:
pluginSettings.getPluginInfo(isPluginProject.getParent()).version;
pluginSettings is a bound variable in the current scope and isPluginProject actually returns a File object that represents the GrailsPlugin.groovy file.
BACKGROUND:
Current Grails application has to interact w/ a 'legacy' web service
from a third party vendor - (systinet) Used the Apache CXF
Wsdl2Java tool to generate complex types and service interfaces.
Pretty standard stuff so far and this works perfectly from Java.
After writing some test classes and main() methods to
exercise the Java code, and providing a thin layer above for a
simplified interface, I wanted to call this code from Grails app.
Specifically, Grails controllers, services, quartz jobs ,and the
like. However, this is where things got interesting.
First stack trace from Grails CXF plug-in it was causing a FileNotFoundException. Beyond not needing to load a WSDL definition - since I already successfully ran CXF's Wsdl2Java tool, it seems there is something I'm missing here. Tried substituting a file:/// url***for the WSDL and got another exception.
At the end of all this -- removing plug-ins of any sort, I reconfigured the project with the CXF dependencies by hand** and now got a MarshallingException, essentially from the CXF-generated code! Which by the way executes perfectly from a Java class.
Someone I am sure must've come across this issue in your Grails integrations. As always your guidance is most appreciated!
1)Why in the Grails application, does the runtime attempt to parse the wsdl ? Also, note JDK versions are same java version "1.6.0_12".
2) Any CLASSPATH workarounds anyone can suggest? I guess an alternative approach is to re-write the Java middle layer calls with GroovyWS but that would be quite an effort - given number of services and the custom types the vendor has baked in.
static {
URL url = null;
try {
url = new URL("http://mydevhost:9080/wasp/bmc-security/ctsa/person");
} catch (MalformedURLException e) {
System.err.println("Can not initialize the default wsdl from server");
// e.printStackTrace();
}
WSDL_LOCATION = url;
}
/* static {
URL url = null;
try {
url = new URL( "file:///C:/Projects/beta/workspace/reqmgr3/wsdl/Person.wsdl" );
url.getPath();
} catch (MalformedURLException e) {
System.err.println("Can not initialize the default wsdl from file system");
// e.printStackTrace();
}
WSDL_LOCATION = url;
} */
`
****Stack traces
INFO: No Trust Decider configured for Conduit ...
Aug 11, 2010 6:26:16 PM org.apache.cxf.transport.http.HTTPConduit finalizeConfig
INFO: No Basic Auth Supplier configured for Conduit '...
Aug 11, 2010 6:26:16 PM org.apache.cxf.transport.http.HTTPConduit prepare
INFO: Chunking is set at 2048.
Aug 11, 2010 6:26:16 PM org.apache.cxf.phase.PhaseInterceptorChain doIntercept
INFO: Interceptor has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Marshalling Error: com.systinet.wsdl.com.bmc.security.ess.webservice.holder.ArrayOfLog
inPairHolder is not known to this context
at org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:132)
at org.apache.cxf.jaxb.io.XMLStreamDataWriter.write(XMLStreamDataWriter.java:42)
at org.apache.cxf.jaxb.io.XMLStreamDataWriter.write(XMLStreamDataWriter.java:30)
at org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutInterceptor.java:73)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:148)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:215)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:122)
at $Proxy44.login(Unknown Source)
...
... 2 more
UPDATE 15-Aug:
Decided, out of both modularity and expediency, to put this code into separate WAR project, which will offer its ltd. services, rather than expose the original vendor web services, which are too unwieldy.
This project will be pure Java and leverages the Metro 2.0.1 runtime, which is around 16mb.
Calling the Java-based middleware services from Grails now becomes possible, after clearing out the lib and src/java folders -- basically just installed ws-client plugin and setup local services such as the following:
import groovyx.net.ws.WSClient
import org.grails.plugins.wsclient.service.WebService
class LocalPersonService {
WebService webService
groovyx.net.ws.WSClient _proxy
static final String PERSON_WSDL_URL = "http://localhost:9090/pri/PersonServicePort?wsdl"
def transactional = false
def getPersonDetails( String customerId, User userAccount, String userCredential ) {
// must cache the proxy
if ( _proxy == null ) {
print( "init proxy. Parsing wsdl..." )
try {
_proxy = webService.getClient(PERSON_WSDL_URL)
}
catch ( Throwable tr ) { println( tr.getMessage() ) }
}
// method shall return a (com.siventures.example.service.PersonDetails)
return _proxy.getPersonDetails( customerId, userAccount, userCredential, ... )
}