Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

When using J/Link, how can we create an array out of objects belonging to different classes but having the same base class?

Here's an example:

partSource = 
  JLink`JavaNew[
   "org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource", "mmagraphics.png", 
   JLink`MakeJavaObject["abcdefg"]@toCharArray[]];
part1 = JLink`JavaNew[
   "org.apache.commons.httpclient.methods.multipart.FilePart", 
   "filename", partSource];
part2 = JLink`JavaNew[
   "org.apache.commons.httpclient.methods.multipart.StringPart", 
   "someting", "1234"];

MakeJavaObject[{part1, part2}]

Java::excptn: A Java exception occurred: java.lang.IllegalArgumentException: array element type mismatch at java.lang.reflect.Array.set(Native Method).

I need to create a Part [] out of {part1, part2} so that I can pass it to the constructor of org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity

share|improve this question
3  
This is for fixing the uploader palette which was broken by API changes today. –  Szabolcs Apr 5 '13 at 0:14
add comment

1 Answer 1

up vote 10 down vote accepted

We can start by creating the parts using the same code as the question:

partSource = 
  JavaNew[
    "org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource",
    "mmagraphics.png", 
    MakeJavaObject["abcdefg"]@toCharArray[]];

part1 =
  JavaNew[
    "org.apache.commons.httpclient.methods.multipart.FilePart", 
    "filename", partSource];

part2 =
  JavaNew[
    "org.apache.commons.httpclient.methods.multipart.StringPart", 
    "someting", "1234"];

We want to create an array whose components are of the type Part. We will need a reference to that class. A normal JLink reference is not good enough -- we need the Java object that represents the class. We use the JLink class loader to get this reference:

LoadJavaClass["com.wolfram.jlink.JLinkClassLoader"];

partClass =
  JLinkClassLoader`classFromName[
    "org.apache.commons.httpclient.methods.multipart.Part"];

We can then use the Array class to create an array of the correct type and fill in its elements:

LoadJavaClass["java.lang.reflect.Array"];

parts =
  ReturnAsJavaObject @ Array`newInstance[partClass, 2];
Array`set[parts, 0, part1]
Array`set[parts, 1, part2]

Note carefully the use of ReturnAsJavaObject. Without it, the carefully constructed array would be immediately converted back to a Mathematica list.

We now have everything we need to construct the required MultipartRequestEntity:

post =
  JavaNew[
    "org.apache.commons.httpclient.methods.PostMethod",
    "http://somewhere/over/the/rainbow"];

multipart = JavaNew[
  "org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity",
  parts,  
  post@getParams[]]

(* JavaObject[org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity] *)
share|improve this answer
    
+1 for the JLinkClassLoader`classFromName[] tip. –  ford Jul 24 '13 at 20:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.