Jaxb unmarshal works on debug but not in runtime - java

I'm trying to use the ACS (Cisco Secure Access Control System) to manage users in the network equipment using code. I've downloaded the examples provided with the product and built upon that, my code.
When I test it in debug mode, everything works great but when I put my .class files in Jboss Web Server and try to execute the main method from another application, I get this error:
unexpected element (uri:identity.rest.mgmt.acs.nm.cisco.com", local:"user"). Expected elements are (none)
my code is:
private static User getUserByName(RestFacade restFacade, String name)
{
User user = null;
String url = "/Rest/Identity/User/name/";
url = url.concat(name);
HttpResponse response = restFacade.get(url);
try {
byte buffer[] = new byte[8192];
int read = 0;
StringBuffer responseBody = new StringBuffer();
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream content = response.getEntity().getContent();
while ((read = content.read(buffer)) != -1) {
responseBody.append(new String(buffer, 0, read));
}
}
ByteArrayInputStream bais = new ByteArrayInputStream(responseBody
.toString().getBytes());
Unmarshaller unmarshaller = JAXBContext.newInstance(User.class).createUnmarshller();
user = (User) unmarshaller.unmarshal(bais);
} catch (Exception e) {
e.printStackTrace();
}
return user;
}
Almost every solution I found for such an error, said to change something in the Rest method I'm trying to invoke or change the xsd, but I don't have access to those..
The weird thing is that it works when I debug from Eclipse but not on runtime. Maybe there's a different version to JAXB I'm using? How can I be sure which jar loads up?
Thank you,
Igor.

That sounds like your development environment you use to debug and your target application server have a different version of either the JAXB classes / library and/or the used XSDs.
The documentation (http://www.cisco.com/c/en/us/td/docs/net_mgmt/cisco_secure_access_control_system/5-3/sdk/acs_sdk/rest.html) specifies the three XSDs (Common, Identity and Query).
Have you verified the version you have (or have downloaded) match the generated JAXB classes on the target application server?

Related

How to get the opened document using UNO?

I'm writing an add-on that opens a dialog and I need to access the currently opened text document but I don't know how get it.
I'm using the OpenOffice plug-in in NetBeans and I started from an Add-on project. It created a class that gives me a XComponentContext instance but I don't know how to use it to get a OfficeDocument instance of the current document.
I've been googling for some time and I can't find any example that uses an existing, opened, document. They all start from a new document or a document that is loaded first so they have an URL for it.
I gave it a try based on the OpenOffice wiki (https://wiki.openoffice.org/wiki/API/Samples/Java/Office/DocumentHandling) and this is what I came up with:
private OfficeDocument getDocument() {
if (this.officeDocument == null) {
try {
// this causes the error
XMultiComponentFactory xMultiComponentFactory = this.xComponentContext.getServiceManager();
Object oDesktop = xMultiComponentFactory.createInstanceWithContext("com.sun.star.frame.Desktop", this.xComponentContext);
XComponentLoader xComponentLoader = UnoRuntime.queryInterface(XComponentLoader.class, oDesktop);
String url = "private:factory/swriter";
String targetFrameName = "_self";
int searchFlags = FrameSearchFlag.SELF;
PropertyValue[] propertyValues = new PropertyValue[1];
propertyValues[0] = new PropertyValue();
propertyValues[0].Name = "Hidden";
propertyValues[0].Value = Boolean.TRUE;
XComponent xComponent = xComponentLoader.loadComponentFromURL(url, targetFrameName, searchFlags, propertyValues);
XModel xModel = UnoRuntime.queryInterface(XModel.class, xComponent);
this.officeDocument = new OfficeDocument(xModel);
} catch (com.sun.star.uno.Exception ex) {
throw new RuntimeException(ex);
}
}
return this.officeDocument;
}
But there is something strange going on. Just having this method in my class, even if it's never been called anywhere, causes an error when adding the add-on.
(com.sun.star.depoyment.DeploymentDescription){{ Message = "Error during activation of: VaphAddOn.jar", Context = (com.sun.star.uno.XInterface) #6ce03e0 }, Cause = (any) {(com.sun.star.registry.CannotRegisterImplementationException){{ Message = "", Context = (com.sun.star.uno.XInterface) #0 }}}}
It seems this line causes the error:
XMultiComponentFactory xMultiComponentFactory = this.xComponentContext.getServiceManager();
I have no idea how to preceed.
I posted this question on the OpenOffice forum but I haven't got a response there. I'm trying my luck here now.
Use this in your code to get the current document:
import com.sun.star.frame.XDesktop;
...
XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, oDesktop);
XComponent xComponent = xDesktop.getCurrentComponent();
I opened the BookmarkInsertion sample in NetBeans and added this code to use the current document instead of loading a new document.
As far as the error, there may be a problem with how it is getting built. A couple of things to check:
Does the Office SDK version match the Office version? Check version number and whether it's 32- or 64-bit.
Make sure that 4 .jar files (juh.jar, jurt.jar, unoil.jar, ridl.jar) are shown under Libraries in NetBeans, because they need to be included along with the add-on.
If you get frustrated with trying to get the build set up correctly, then you might find it easier to use python, since it doesn't need to be compiled. Also python does not require queryInterface().

Getting the jsp source code appended with the file content when I download files

I am working on a File upload/download functionality, in Java using Struts2 framework, where we are uploading to and downloading from a remote server path. All seems to work fine when I check the functionality at my local machine with a local path as the destined path from where i am downloading and to which am uploading the files of any format. The development environment has JBoss server.
But when I run the same over at the prod env, where the application is deployed in Weblogic server, files of .txt,.csv,.html (basically text format files) have my jsp source code appended to the file content.
Below is the code that I have used for downloading:
BufferedOutputStream bout=null;
FileInputStream inStream = null;
byte[] buffer = null;
try {
inStream = new FileInputStream(path+File.separator+filename);
buffer = new byte[8192];
String extension = "";
int pos = filename.lastIndexOf(".");
if (pos > 0)
extension = filename.substring(pos+1);
int bytesRead = 0, bytesBuffered = 0;
response.setContentType("application/octet-stream");
response.setHeader("content-disposition", "attachment; filename="+ filename);
bout = new BufferedOutputStream(response.getOutputStream());
while((bytesRead = fistrm.read(buffer)) > -1){
bout.write(buffer, 0, bytesRead);
bytesBuffered += bytesRead;
if(bytesBuffered > 1048576){
bytesBuffered = 0;
bout.flush();
}
}
} catch (IOException e) {
log.error(Logger.getStackTrace(e));
} finally {
if(bout!=null){
bout.flush();
bout.close();
}
if(inStream!=null)
inStream.close();
}
I have tried using different response content types with respect to the extension, but it was of no help.
Seems like the outputstream has the jsp source code in it even before writing from the inputstream.
Can anyone please suggest a solution and explain why is this happening ?
It is happening because you are writing directly in the outputstream, and then returning a struts result, that is your JSP. You are using an action as if it would be a servlet, which is not.
In Struts2, to achieve your goal, you need to use the Stream result type, as described in the following answers:
https://stackoverflow.com/a/16300376/1654265
https://stackoverflow.com/a/16900840/1654265
Otherwise, if you want to bypass the framework mechanisms and manually write to the outputStream by yourself (there are very rare cases in which it is useful, like downloading dynamically created ZIP), then you must return the NONE result.
Returning ActionSupport.NONE (or null) from an Action class method causes the results processing to be skipped. This is useful if the action fully handles the result processing such as writing directly to the HttpServletResponse OutputStream.
But I strongly suggest you to go with the Stream result, the standard way.

Java Spring Boot Restcontroller RequestMapping executed twice

I have a Spring Boot Application with a RestController and a method which will download and pass an image:
#RestController
public class PictureController {
#RequestMapping("/picture/{id}")
public HttpEntity<byte[]> getImage(#PathVariable String id) {
logger.info("Requested picture : >> " + id + " <<");
// !! Execute code for downloading !!
// Create Headers...
// return HttpEntity<byte[]>
}
}
In the logfiles I can read that the method is executed twice and I don't know why.
If I remove the code for downloading it gets executed just once as expected.
Is it because it takes a second to download it?
The code for downloading is...
byte[] response;
try {
URL url = new URL(....);
InputStream in = new BufferedInputStream(url.openStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n = 0;
while (-1 != (n = in.read(buf))) {
out.write(buf, 0, n);
}
out.close();
in.close();
response = out.toByteArray();
I also tried several solutions like...
#RequestMapping(value = "/picture2/{id}", headers = "Accept=image/jpeg, image/jpg, image/png, image/gif")
public #ResponseBody byte[] getArticleImage2(#PathVariable String id) {
I thought maybe a problem with HttpEntity but it's the same behaviour. Works as expected without code for downloading but with downloading an image it gets executed twice.
This is a serious performance issue of my application... :(
What is the problem here?
The problem depends on the Browser which is used to test the RestController.
I'am using Firefox... and Firefox tend to get some html around an image. But the method doesn't return html and so Firefox is starting another request... also for looking for a favicon.
Internet Explorer e.g. doesn't care about it and the method is only executed once as expected!
So my problem is not a real problem because later my image delivered by the RestController will be embedded in a website which has html and a favicon.

Disabling Multipart Caching in CXF jax-rs

I posted this question to the CXF list, without any luck. So here we go. I am trying to upload large files to a remote server (think of them virtual machine disks). So I have a restful service that accepts upload requests. The handler for the upload looks like:
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Path("/doupload")
public Response receiveStream(MultipartBody multipart) {
List<Attachment> allAttachments = body.getAllAttachments();
Attachment att = null;
for (Attachment b : allAttachments) {
if (UPLOAD_FILE_DESCRIPTOR.equals(b.getContentId())) {
att = b;
}
}
Assert.notNull(att);
DataHandler dh = att.getDataHandler();
if (dh == null) {
throw new WebApplicationException(HTTP_BAD_REQUEST);
}
try {
InputStream is = dh.getInputStream();
byte[] buf = new byte[65536];
int n;
OutputStream os = getOutputStream();
while ((n = is.read(buf)) > 0) {
os.write(buf, 0, n);
}
ResponseBuilder rb = Response.status(HTTP_CREATED);
return rb.build();
} catch (IOException e) {
log.error("Got exception=", e);
throw new WebApplicationException(HTTP_INTERNAL_ERROR);
} catch (NoSuchAlgorithmException e) {
log.error("Got exception=", e);
throw new WebApplicationException(HTTP_INTERNAL_ERROR);
} finally {}
}
The client for this code is fairly simple:
public void sendLargeFile(String filename) {
WebClient wc = WebClient.create(targetUrl);
InputStream is = new FileInputStream(new File(filename));
Response r = wc.post(new Attachment(Constants.UPLOAD_FILE_DESCRIPTOR,
MediaType.APPLICATION_OCTET_STREAM, is));
}
The code works fine in terms of functionality. In terms of performance, I noticed that before my handler (receiveStream() method) gets the first byte out of the stream, the whole stream actually gets persisted into a temporary file (using a CachedOutputStream). Unfortunately, this is not acceptable for my purposes.
My handler simply passes the incoming bytes to a backend storage system (virtual machine disk repository), and waiting for the whole disk to be written to a cache only to be read again takes a lot of time, tying up a lot of resources, and reducing throughput.
There is a cost associated with writing the blocks and reading them again, since the app is running in the cloud, and the cloud provider charges per block read/written.
Since every byte is written to the local disk, my service VM must have enough disk space to accommodate the total sizes of all the streams being uploaded (i.e., if I have 10 uploads of 100GB each, I must have 1TB of disk just to cache the content). That again is extra money, as the size of the service VM grows dramatically, and the cloud provider charges for the provisioned disk size as well.
Given all of this, I am looking for a way to use the HTTP InputStream (or as close to it as possible) to read the attachment directly from there and handle it afterwards. I guess the question translates into one of:
- Is there a way to tell CXF not do caching
- OR - is there a way to pass CXF an output stream (one I write) to use, rather than using CachedOutputStream
I found a similar question here. The resolution says use CXF 2.2.3 or later, I am using 2.4.4 (and tried with 2.7.0) with no luck.
Thanks.
I think it's logically not possible (neither in CXF or anywhere else). You're calling getAllAttachements(), which means that the server should collect information about them from the HTTP input stream. It means that the entire stream has to go into memory for MIME parsing.
In your case you should work directly with the stream, and do the MIME parsing yourself:
public Response receiveStream(InputStream input) {
Now you have full control of the input and can consume it into memory byte-by-byte.
I ended up fixing the problem in an unelegant way, but it works, so I wanted to share my experience. Please do let me know if there are some "standard" or better ways.
Since I am writing the server side, I knew I was accessing all the attachments in the order they were sent, and process them as they are streamed in. So, to reflect that behavior of the handler method (receiveStream() method above), I created a new annotation on the server side called "#SequentialAttachmentProcessing" and annotatated my above method with it.
Also, wrote a subclass of Attachment, called SequentialAttachment that acts like a linked list. It has a skip() method that skips over the current attachment, and when an attachment ends, hasMore() method tells you whether there is another one.
Then I wrote a custom multipart/form-data provider which behaves as follows: If the target method is annotated as above, handle the attachment, otherwise call the default provider to do the handling. When it is handled by my provider, it always returns at most one attachment. Hence it could be misleading to a non-suspecting handling method. However, I think it is acceptable since the writer of the server must have annotated the method as "#SequentialAttachmentProcessing" and therefore must know what that entails.
As a result the implementation of the receiveStream() method is now something like:
#POST
#SequentialAttachmentProcessing
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Path("/doupload")
public Response receiveStream(MultipartBody multipart) {
List<Attachment> allAttachments = body.getAllAttachments();
Assert.isTrue(allAttachments.size() <= 1);
if (allAttachment.size() > 0) {
Attachment head = allAttachments.get(0);
Assert.isTrue(head instanceof SequentialAttachment);
SequentialAttachment att = (SequentialAttachment) head;
while (att != null) {
DataHandler dh = att.getDataHandler();
InputStream is = dh.getInputStream();
byte[] buf = new byte[65536];
int n;
OutputStream os = getOutputStream();
while ((n = is.read(buf)) > 0) {
os.write(buf, 0, n);
}
if (att.hasMore()) {
att = att.next();
}
}
}
}
While this solved my immediate problem, I still believe there has to be a standard way of doing this. I hope this helps someone.

java.lang.nosuchfielderror in j2me app

Hey Hi Friends I am created one j2me app. it runs perfectly in Emulator but in Mobile it showing error like java.lang.nosuchfielderror:No such field HEADERS.[[Ljava/lang/String;.
Why this happening with mobile, it runs good in emulator......
Please help me to remove this error......
public String connectPhoneName() throws Exception{
String url = "http://122.170.122.186/Magic/getPhonetype.jsp";
String phoneType;
if ((conn = connectHttp.connect(url, HEADERS)) != null) {
if ((in = connectHttp.getDataInputStream(conn)) != null) {
byte[] data = connectHttp.readDATA(in, 100);
phoneType = new String(data);
System.out.println("DATA : " + phoneType);
} else {
throw new Exception("ERROR WHILE OPENING INPUTSTREAM");
}
} else {
throw new Exception("COULD NOT ESTABLISH CONNECTION TO THE SERVER");
}
return phoneType;
}
In this code i have used HEADERS.
It looks like your app is using some (I guess) or static final or final field of some library class that does not exist in the profile of Java ME your mobile device implements.
But I can't figure out where that field comes from. Perhaps you should search your codebase for use of "HEADER" as an identifier ...
If the HEADER field is properly declared in your codebase (your MagiDEF interface) and the code you showed is using the HEADER from that interface, then you must have something wrong with your build or deployment process. Specifically, you are not deploying the version of MagiDEF that your code (above) has been compiled against. Maybe you've got an old version of something in some JAR file?
Basically, the error indicates that you have a binary incompatibility between some of the classes / interfaces that make up your app.

Categories