I'm completely stumped as to why this is happening and the stack trace I get isn't really helpful to me. I'm sending a post request to one of my controllers in Grails. The action handling the request is as follows:
def save() {
def files = request.getFiles("images")
def json = JSON.parse(request.getParameter("json"))
// Redacted
}
Looping over images and json separately works fine:
files.each {
println it
}
json.each {
println it
}
But nesting them does not:
files.each { img ->
json.each { jsn ->
println "$img: $jsn"
}
}
What I'm trying to do is the user uploads X amount of images and a json payload. The json would contain new names for the uploaded files, so I would loop through each file and rename it to the name specified in the json. So I'm trying to achieve something like this (assuming same files and json are of equal sizes):
files.each { image ->
json.names.each { newName ->
image.renameTo(new File(destination, "$newName.jpg"))
}
}
It's strange that it doesn't work as in my index action I'm doing that same thing:
categories.each { category ->
images.each { image ->
// Redacted
}
}
However the difference here is that categories and images are both defined as instance variables of the controller:
private categories = []
private images = []
Stack trace:
URI: /api/images/save
Class: java.lang.NoSuchMethodError
Message: null
Caused by: gabriel.ApiController$_save_closure6: method <init (Ljava/lang/Object;Ljava/lang/Object;)V not found
Line | Method
->> 1142 | runWorker in java.util.concurrent.ThreadPoolExecutor
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 617 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . in java.lang.Thread
Caused by NoSuchMethodError: gabriel.ApiController$_save_closure6: method <init>(Ljava/lang/Object;Ljava/lang/Object;)V not found
->> 91 | save in ApiController.groovy
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1142 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 617 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
Doing a Build -> Rebuild Project seems to have fixed the issue.
files.each {file,index->
File img = new File( json[index])
file.transferTo(img)
}
Related
Using the serde and url_serde crates, I get errors suggesting I need to fulfill unrelated trait bounds:
Compiling ser v0.1.0 (/data/scratch/ser)
error[E0277]: the trait bound `for<'a> url_serde::Ser<'a, url::Url>: a::_::_serde::Serialize` is not satisfied
--> src/b.rs:4:10
|
4 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^ the trait `for<'a> a::_::_serde::Serialize` is not implemented for `url_serde::Ser<'a, url::Url>`
|
::: /home/danj/.cargo/registry/src/github.com-1ecc6299db9ec823/url_serde-0.2.0/src/lib.rs:77:46
|
77 | where S: Serializer, for<'a> Ser<'a, T>: Serialize
| --------- required by this bound in `url_serde::serialize`
|
= help: the following implementations were found:
<url_serde::Ser<'a, std::option::Option<url::Url>> as a::_::_serde::Serialize>
<url_serde::Ser<'a, url::Url> as a::_::_serde::Serialize>
<url_serde::Ser<'a, url::host::Host<String>> as a::_::_serde::Serialize>
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `url_serde::De<url::Url>: a::_::_serde::Deserialize<'_>` is not satisfied
--> src/b.rs:4:21
|
4 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^ the trait `a::_::_serde::Deserialize<'_>` is not implemented for `url_serde::De<url::Url>`
|
::: /home/danj/.cargo/registry/src/github.com-1ecc6299db9ec823/url_serde-0.2.0/src/lib.rs:158:40
|
158 | where D: Deserializer<'de>, De<T>: Deserialize<'de>
| ---------------- required by this bound in `url_serde::deserialize`
|
= help: the following implementations were found:
<url_serde::De<std::option::Option<url::Url>> as a::_::_serde::Deserialize<'de>>
<url_serde::De<url::Url> as a::_::_serde::Deserialize<'de>>
<url_serde::De<url::host::Host> as a::_::_serde::Deserialize<'de>>
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.
error: could not compile `ser`.
To learn more, run the command again with --verbose.
Cargo.toml
[package]
name = "ser"
version = "0.1.0"
authors = ["..."]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { version = "1.0.115", features = ["derive"] }
url = "2.1.1"
url_serde = "0.2.0"
src/lib.rs:
pub mod a;
pub mod b;
src/a.rs:
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct A {
pub name: String,
}
src/b.rs:
use serde::{Deserialize, Serialize};
use url::Url;
#[derive(Serialize, Deserialize)]
pub struct B {
#[serde(with = "url_serde")]
uri: Url,
}
Found this through crates.io linking to an upgrade: https://github.com/servo/rust-url/blob/b03895bd479d72c75600dc09c8c7906f5ee203ea/UPGRADING.md
tl;dr
url = { version = "2.0", features = ["serde"] }
and remove all references to url_serde
I'd like to set the baseUrl for a table based on the outcome of another test (on the same page).
I tried following these pages of Fitnesse's docs (and other resources) :
smartrics blog post, fitnesse symbols page,
but I can't seem to get it working.
So far I've tried with the following syntaxes :
| Fit Rest Fixture | %emailLink% |
| GET | / | 200 |Content-Type: text/plain|Email Verified|
| Fit Rest Fixture | emailLink= |
| GET | / | 200 |Content-Type: text/plain|Email Verified|
| Fit Rest Fixture | $emailLink |
| GET | / | 200 |Content-Type: text/plain|Email Verified|
but none of those work.
I know that the emailLink symbol is not null because I'm testing it in another table, but I can't seem to inject it into the RestFixture.
I always get an IllegalArgumentException indicating that the symbol name has not been resolved against its value, e.g.
java.lang.IllegalArgumentException: Malformed base URL: $emailLink
Any help would be appreciated.
Are you using slim?
http://www.fitnesse.org/FitNesse.UserGuide.WritingAcceptanceTests.SliM.SymbolsInTables
I have used symbols in this way a few time with Slim, but not the REST Fixture specifically.
By taking a look at the code of FitRestFixture and fiddling with it, I've come up with something that works for me.
It seems that the feature I was looking for is not supported out of the box, but can be easily achieved (although this way is not the cleanest) with a simple mod such as the following :
/**
* #return Process args ({#link fit.Fixture}) for Fit runner to extract the
* baseUrl of each Rest request, first parameter of each RestFixture
* table.
*/
protected String getBaseUrlFromArgs() {
String arg = null;
if (args.length > 0) {
arg = args[0];
/* mod starts here */
if (isSymbol(arg)) {
String symbolName = stripSymbolNotation(arg);
arg = resolveSymbol(symbolName);
}
/* mod ends here */
}
return arg;
}
private boolean isSymbol(String arg) {
// notice that I've used the '<<' notation convention to extract the
// the value from a symbol, while in RestFixture the conventional
// notation is %symbolName%
return null != arg && arg.startsWith("<<");
}
private String stripSymbolNotation(String arg) {
return arg.substring(2);
}
private String resolveSymbol(String arg) {
String symbolValue = (String) Fixture.getSymbol(arg);
LOG.warn(String.format("resolved symbol %s to value %s", arg, symbolValue));
return symbolValue;
}
I have two objects. One called EstimateItem and the other one is called Part (Part class is inherited from Realm's Object class). One EstimateItem can have multiple Parts.
class EstimateItem {
var parts: [Part]?
}
There's an array of EstimateItems with different numbers of Parts in each instance.
+--------------------------------+---------------------------------+
| EstimateItem | Parts |
+--------------------------------+---------------------------------+
| Line Item 1 - RnR WDH - Twins | Epoxy / Wood for lami |
| (single) | |
| | |
| Line Item 2 - RnR WDH - Twins | Epoxy / Wood for lami |
| (double) | |
| | |
|Line Item 3 - Install sash lock |Epoxy / Wood for lami / Sash lock|
+--------------------------------+---------------------------------+
I need to group them by specific Part. It should look something like this.
How do I do this?
I couldn't figure out a way to do this while the parts are attached to individual item so I tried laying them all out in an array of (part: Part, item: EstimateItem) tuples.
var groups = [(part: Part, item: EstimateItem)]()
for item in estimateItemsArray {
if let parts = item.parts {
for part in parts {
groups.append((part, item))
}
}
}
// Epoxy - RnR WDH - Twins (single)
// Wood for lami - RnR WDH - Twins (single)
// Epoxy - RnR WDH - Twins (double)
// Wood for lami - RnR WDH - Twins (double)
// Epoxy - RnR WDH - Twins (single)
// Wood for lami - RnR WDH - Twins (single)
// Sash lock, traditional - Install sash lock
And then group it.
But I'm still stuck. Also I feel like I'm overcomplicating it and I was wondering if there's an easier and more Swifty way of doing this.
What I came up with trying to find a more swifty way of doing this is the following:
let parts = Set(estimateItemsArray.flatMap{ $0.parts ?? [] })
let partMap = parts.map { part in
return (part, estimateItemsArray.filter {
$0.parts?.indexOf(part) != nil
}
)
}
partMap now contains tuples of the form (Part, [EstimateItem]). The only requirement is for Part to conform to Hashable or something related - in my test I just let Part inherit from NSObject.
Explanation:
create an array of all the available parts (Set to ensure uniqueness)
loop over the array mapping and returning a tuple of
the actual part
loop over estimateItemsArray filtering out the items that have the current part in their list
The complete test-data looks like this
/* the now classes, both include some identifier to distinguish them */
class Item {
var n : String
var parts : [Part]? = [Part]()
init(n:String) {
self.n = n
}
}
class Part : NSObject {
var n : String
init(n:String) {
self.n = n
}
}
/* set up the test data */
let item1 = Item(n: "item 1")
let item2 = Item(n: "item 2")
let item3 = Item(n: "item 3")
let part1 = Part(n: "part 1")
let part2 = Part(n: "part 2")
let part3 = Part(n: "part 3")
item1.parts = [part1, part2]
item2.parts = [part1, part3]
item3.parts = [part1, part2, part3]
var arrItems = [item1, item2, item3]
/* actual logic */
let parts = Set(arrItems.flatMap{ $0.parts ?? [] })
let partMap = parts.map { part in
return (part, arrItems.filter {
$0.parts?.indexOf(part) != nil
}
)
}
/* final output */
partMap.forEach { entry in
print("part \(entry.0.n)")
entry.1.forEach {
print("contains \($0.n)")
}
}
Outputting:
part part 1
contains item 1
contains item 2
contains item 3
part part 3
contains item 2
contains item 3
part part 2
contains item 1
contains item 3
If you cannot inherit from NSObject like I initially though, make your class Part conform to Hashable which is the requirement for sets:
class Part : Hashable {
var n : String
init(n:String) {
self.n = n
}
var hashValue: Int {
return n.hashValue // you basically have to provide some kind of logic based on *your* Part object
}
}
func ==(lhs: Part, rhs: Part) -> Bool {
return lhs.hashValue == rhs.hashValue
}
So... Is there a way to do something like this?
class Kitty {
String name
String nickName
public static String getExpectedNickname(String name) {
return name.replaceAll('Mr. ', '')
}
static namedQueries = {
byKityWithPredictableNickname {
ilike 'name', '%Kitty%'
ilike 'nickName', Kitty.getExpectedNickname('name')
}
}
}
Can I reference the value of the current row's column value somehow? I thought property('name') would work, but alas, no.
EDIT:
Another example: I thought something like this would work... but it doesn't :( ...
static namedQueries = {
whyDoesntThisReturnEverything {
int c = Kitty.bySubQuery(id).count() //returns everything when I put "1" instead of "id"
c == 1
}
bySubQuery { Long paramId ->
eq 'id', paramId
}
}
Instead I get some stupid illegal argument exception:
java.lang.ClassCastException#2af65a43. Stacktrace follows:
Message: java.lang.ClassCastException#2af65a43
Line | Method
->> -1 | invoke in sun.reflect.GeneratedMethodAccessor327
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 43 | invoke in sun.reflect.DelegatingMethodAccessorImpl
| 606 | invoke . . . . . . . . . . . . . . . in java.lang.reflect.Method
| 1254 | jlrMethodInvoke in org.springsource.loaded.ri.ReflectiveInterceptor
| 90 | invoke . . . . . . . . . . . . . . . in org.codehaus.groovy.reflection.CachedMethod
| 57 | getProperty in groovy.lang.MetaBeanProperty
...
I think the only way to do this is through sqlRestriction.
//...
static namedQueries = {
findAllKitty {
ilike 'name', '%Kitty%'
}
findAllByNickNameLikeName {
sqlRestriction "nick_name like '%' || replace(name, 'Mr. ', '') || '%' "
}
}
//to use:
Kitty.findAllByNickNameLikeName().list()
The SQL syntax will probably change depending on the database you are using.
Need a little help with the closure part of this, and maybe a bit more. I'm trying to call a stored procedure in Oracle 11g from my Grails service.
So far:
import java.sql.*
import groovy.sql.Sql
import oracle.jdbc.driver.OracleTypes
class DummyService {
def dataSource
def serviceMethod() {
}
def listPeople(){
Sql sql = new groovy.sql.Sql(dataSource)
def resultList = []
sql.call("BEGIN mypackage.p_get_people(?); END;",
[Sql.resultSet(OracleTypes.CURSOR)]) {cursorResults ->
if(cursorResults.next()) {
results = cursorResults.getAt(1);
}
}
return resultList
}
Alright, so this returns the first rows data, and depending on what is passed to the getAt() method, I can grab that column. Which I found here ORACLE STORED PROCS IN GRAILS
What I really want is to return the result set and put it into a list, I'm just not sure how to do it.
When I try {cursorResults -> println cursorResults} it throws an error
Message: org.apache.commons.dbcp.DelegatingCallableStatement with Address: "oracle.jdbc.driver.T4CCallableStatement#...."is closed
Running this procedure directly in Oracle there is 457 rows in the cursor, if that helps at all.
Edit 1:
Response to dmahapatro, this is the NPE
| Error 2013-05-07 14:16:05,123 [http-bio-8080-exec-1] ERROR errors.GrailsExceptionResolver - NullPointerException occurred when processing request: [GET] /testapp/messages/list
Stacktrace follows:
Message: null
Line | Method
->> 15 | list in testapp.MessagesController$$EO5AzzAw
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 195 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 886 | runTask in java.util.concurrent.ThreadPoolExecutor$Worker
| 908 | run . . in ''
^ 662 | run in java.lang.Thread
And right now line 15 is simply println dummyService.listPeople()
sql.call results to GroovyResultSet. You should be able to do an eachRow on the resultset and push it to the list.
def listPeople(){
Sql sql = new groovy.sql.Sql(dataSource)
def resultList = []
sql.call("BEGIN mypackage.p_get_people(?); END;",
[Sql.resultSet(OracleTypes.CURSOR)]) {cursorResults ->
cursorResults.eachRow{result ->
resultList << result
}
}
return resultList
}
EDIT:
Alternatively using sql.eachRow
sql.eachRow("BEGIN mypackage.p_get_people(?); END;",
[Sql.resultSet(OracleTypes.CURSOR)]) {row ->
resultList << row
}
the only thing that did work for me is this:
def array = []
sql.call("begin SCHEMA.PKG_NAME.PROCEDURE_NAME(${personId},${Sql.resultSet OracleTypes.CURSOR}); end;")
{rset ->
rset.eachRow(){
array.add(["NAME":it.getString("TABLE_COLUMN_NAME"),"DESC":it.getString("TABLE_COLUMN_DESC")])
}
}
When I wasn't using it.getString("TABLE_COLUMN_NAME") it'd threw me a NULL error on everything I try to "println"