I am working on a project to connect test instruments and get request and response from it using webservice.
I have to request more than one service from the instrument, but when I use more than two #Gets in the server, I get an error in my browser saying
Cannot access WADL, please restart your restful webservice
This is my code,
GET
#Produces("text/html")
public String getHtml(){
String ins_name=null;
try {
String [] env=null;
//setting the environment variable.
String[]callAndArgs= {"python","instrument_name.py"};//Python and file name
Process p = Runtime.getRuntime().exec(callAndArgs,env,
new java.io.File("C:\\fakepath\\NetBeansProjects\\DemoApp1\\build\\web"));//executing Python file
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));//getting the value from Python file
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));// reading the error
ins_name = stdInput.readLine();//reading the output from the Pythonfile
System.out.println(ins_name);
}
catch (IOException e) {//catching the exception
System.out.println("exception occured");
e.printStackTrace();
System.exit(-1);
}
return ins_name;//returning the instrument name
}
#GET
#Produces("text/html")
public String getHtml1() {
String check=null;
String c1="hjhj";
String [] env=null;
//setting the environment variable.
try{
String[] callAndArgs= {"python","check_connection.py",c1};//Python and file name
Process p = Runtime.getRuntime().exec(callAndArgs,env,
new java.io.File("C:\\Users\\Balkishore\\Documents\\NetBeansProjects\\DemoApp1\\build\\web"));//executing Python file
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));//getting the value from Python file
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));// reading the error
check= stdInput.readLine();//reading the output from the Python file
System.out.println();
}
catch (IOException e) {//catching the exception
System.out.println("exception occured");
e.printStackTrace();
System.exit(-1);
}
return check;
}
/**
* Web service operation
}
/**
* PUT method for updating or creating an instance of GenericResource
* #param content representation for the resource
* #return an HTTP response with content of the updated or created resource.
*/
#PUT
#Consumes("text/html")
public String putHtml(String interface_name) {
try {
String [] env=null;
String [] callAndArgs= {"python","connection.py",this.interface_name=interface_name};//Python file with arguments
Process p = Runtime.getRuntime().exec(callAndArgs,env,
new java.io.File("C:\\fakepath\\NetBeansProjects\\DemoApp1\\build\\web"));//executing the Python file
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));//getting the input
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));//getting the error
interface_name = stdInput.readLine();//reading the output
System.out.println(interface_name);
}
catch (IOException e) {//catching the exception
System.out.println("exception occured");
e.printStackTrace();
System.exit(-1);
}
return interface_name;
}
}
I have also attached the image of the error message.
You can't define distinct "GET" for a resource unless you specify distinct Path for your methods #Path("/mypath") in addition to your resource path
#Path("/myRes")
public class myResource{
#GET #Path("/myAttr")
public void getAttr(...)
}
Related
I am working on drool dtable xls file with spring.
i have implemented the business rules in xls file using external location and then with the help of kie services i am executing rules.
Following is the code snippet that's how i am loading rules in engine.
at the start of spring initialization i am calling init() method
see below spring configuration.
<bean id="droolsService" class="com.example.drools.DroolsServiceImpl" init-method="init">
Java Code
public void init() {
LOG.info("inside init");
KieSession kieSession;
for (RequestType type : droolsMap.keySet()) {
try {
kieSession = getKieSession(this.getDroolsMap().get(type));
droolsRules.put(type, kieSession);
} catch (Exception e) {
LOG.error("Failed to load kiesession:", e);
throw new RuntimeException(e);
}
}
}
private KieSession getKieSession(final String file) throws DroolsParserException, IOException, BiffException {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
InputStream stream = null;
String drl = null;
String RULE_PATH = "src/main/resources/";
SpreadsheetCompiler converter = new SpreadsheetCompiler();
//Workbook workbook = Workbook.getWorkbook(DroolsServiceImpl.class.getResourceAsStream(file));
Workbook workbook = Workbook.getWorkbook(new FileInputStream(file));
LOG.info("Loading rule file " + file);
for (Sheet sheet : workbook.getSheets()) {
LOG.info("Loading Sheet " + sheet.getName());
stream = new FileInputStream(file);
drl = converter.compile(stream, sheet.getName());
//StringReader reader = new StringReader(drl);
String DRL_FILE = RULE_PATH + sheet.getName() + ".drl";
System.out.println("Drool file added ::: " + DRL_FILE);
kfs.write(DRL_FILE, ResourceFactory.newReaderResource(new StringReader(drl)));
stream.close();
}
KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
KieSessionConfiguration conf = SessionConfiguration.newInstance();
KieSession ksession = kieContainer.newKieSession(conf);
if (kieBuilder.getResults().hasMessages(Message.Level.ERROR)) {
List<Message> errors = kieBuilder.getResults().getMessages(Message.Level.ERROR);
StringBuilder sb = new StringBuilder("Errors:");
for (Message msg : errors) {
sb.append("\n " + msg);
}
try {
throw new Exception(sb.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null)
stream.close();
if (workbook != null)
workbook.close();
}
}
return ksession;
}
Everything working perfect but the problem is i am not able to scan the file changes. If files is modified then i have to restart the server in order to sync the changes.
I have tried listener to load specific init() method after xls dtable has any changes but its not working , same old result is coming.
I have tried kiescanner but i am not able to get the concept.
KieScanner is loading maven kjar so how do i suppose to create kjar.
I just wanted to kie api scan if any changes in the drool file and try to reload whole changes in kiecontainer without server restarting.
Found the answer myself, Posting because it will help someone who needed.
What I did , I have used apache VFS File Monitor-
DefaultFileMonitor fm = new DefaultFileMonitor(new CustomFileListener());
When file will modified , create or get deleted it will call CustomFileListener.
Following is the implementation of CustomFileListener.
import org.apache.commons.vfs2.FileChangeEvent;
import org.apache.commons.vfs2.FileListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.support.XmlWebApplicationContext;
public class CustomFileListener implements FileListener {
private static final Logger LOG = LoggerFactory.getLogger(CustomFileListener.class);
#Override
public void fileCreated(FileChangeEvent fileChangeEvent) throws Exception {
}
#Override
public void fileDeleted(FileChangeEvent fileChangeEvent) throws Exception {
}
#Override
public void fileChanged(FileChangeEvent fileChangeEvent) throws Exception {
LOG.debug(" Under FileChanged Method");
LOG.debug(" File has been changed hence reinitializing init method = " + fileChangeEvent.getFile().getName().getPath());
XmlWebApplicationContext xmlWebApplicationContext =
(XmlWebApplicationContext) ContextLoader.getCurrentWebApplicationContext();
DefaultListableBeanFactory defaultListableBeanFactory =
(DefaultListableBeanFactory) xmlWebApplicationContext.getBeanFactory();
DroolsServiceImpl droolsService = (DroolsServiceImpl) defaultListableBeanFactory.getBean("droolsService");
droolsService.init();
}
}
What i did when the file will change, It will call fileChanged method.
In that i have fetched cached bean(DroolServiceImpl) from ContextLoader.getCurrentWebApplicationContext(); and called its init() method.
So this it will reload whole process and reinitialize the KieModule,KieRepository.
I built a web application using spring MVC, everything is working fine except the file upload in which I got random FileNotFoundExceptions. I found some solutions online like using a different tmp folder but I keep getting random error.
My code is:
#RequestMapping(value="/upload", method=RequestMethod.POST)
public #ResponseBody String handleFileUpload(#RequestParam("file") final MultipartFile multipartFile,
#RequestHeader("email") final String email, #RequestHeader("password") String password){
if (authenticateUser(email, password)) {
if (!multipartFile.isEmpty()) {
System.out.println("Start processing");
Thread thread = new Thread(){
public void run(){
ProcessCSV obj = new ProcessCSV();
try {
File file = multipartToFile(multipartFile);
if(file !=null) {
obj.extractEvents(file, email, cluster, session);
}
else {
System.out.println("null File");
}
} catch (IOException e) {
System.out.println("File conversion error");
e.printStackTrace();
}
}
};
thread.start();
return "true";
} else {
return "false";
}
}
else {
return "false";
}
}
and:
public File multipartToFile(MultipartFile multipartFile) throws IOException {
File uploadFile = null;
if(multipartFile != null && multipartFile.getSize() > 0) {
uploadFile = new File("/tmp/" + multipartFile.getOriginalFilename());
FileOutputStream fos = null;
try {
uploadFile.createNewFile();
fos = new FileOutputStream(uploadFile);
IOUtils.copy(multipartFile.getInputStream(), fos);
} catch (FileNotFoundException e) {
System.out.println("File conversion error");
e.printStackTrace();
} catch (IOException e) {
System.out.println("File conversion error");
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
System.out.println("File conversion error");
e.printStackTrace();
}
}
}
}
else {
System.out.println("null MultipartFile");
}
return uploadFile;
}
and the configuration file:
multipart.maxFileSize: 100MB
multipart.maxRequestSize: 100MB
multipart.location = ${user.home}
server.port = 8090
I used different versions of the multipartToFile function, one was using multipartfile.transferTo() but I was getting the same random error. Any advice?
Thank you
EDIT stack trace:
java.io.IOException: java.io.FileNotFoundException: /Users/aaa/upload_07720775_4b37_4b86_b370_40280388f3a4_00000003.tmp (No such file or directory)
at org.apache.catalina.core.ApplicationPart.write(ApplicationPart.java:121)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.transferTo(StandardMultipartHttpServletRequest.java:260)
at main.RESTController.multipartToFile(RESTController.java:358)
at main.RESTController$1.run(RESTController.java:241)
Caused by: java.io.FileNotFoundException: /Users/aaa/upload_07720775_4b37_4b86_b370_40280388f3a4_00000003.tmp (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.write(DiskFileItem.java:392)
at org.apache.catalina.core.ApplicationPart.write(ApplicationPart.java:119)
... 3 more
I had just had a night of terror with this error. I found out that MultiPartFile is only recognisable to and by the #Controller class. So if you pass it to another bean which is not a controller, Spring will not be able to help you. It somewhat makes sense that the #Controller is tightly bound to the front screen (communication from the browser to the system - Controllers are the entry point from the browser). So any conversation must happen there in the Controller.
In my case, I did something like the following:
#Controller
public class FileUploadingController{
#PostMapping("/uploadHistoricData")
public String saveUploadedDataFromBrowser(#RequestParam("file") MultipartFile file) {
try {
String pathToFile = "/home/username/destination/"
new File(pathToFile).mkdir();
File newFile = new File(pathToFile + "/uploadedFile.csv");
file.transferTo(newFile); //transfer the uploaded file data to a java.io.File which can be passed between layers
dataService.processUploadedFile( newFile);
} catch (IOException e) {
//handle your exception here please
}
return "redirect:/index?successfulDataUpload";
}
}`
I had the same problem, it looks like MultipartFile is using different current dir internally, so all not absolute paths are not working.
I had to convert my path to an absolute path and then it worked.
It is working inside #RestController and in other beans too.
Path path = Paths.get(filename).toAbsolutePath();
fileToImport.transferTo(path.toFile());
fileToImport is MultipartFile.
I have a Spring MVC controller that accepts a MultipartFile, which will be a zip file. The problem is I can't seem to go from that to a ZipInputStream or ZipFile, so that I can go through the entries. It either closes the stream prematurely, produces an empty file, or as in the case below, zipInputStream.getNextEntry() returning null.
This is my MVC controller:
#RequestMapping(value = "/content/general-import", method = RequestMethod.POST)
public ModelAndView handleGeneralUpload(
#RequestParam("file") MultipartFile file) throws IOException {
// hard code the signature for the moment
String signature = "RETAILER_GROUP:*|CHANNEL:*|LOCALE:de-AT|INDUSTRY:5499";
LOG.info("Processing file archive: {} with signature: {}.", file.getName(), signature);
ModelAndView mav = new ModelAndView();
mav.setViewName("contentUpload");
LOG.debug("File={} is empty={}.", file.getName(), file.isEmpty());
if (!file.isEmpty()) {
processFileZipEntry(file, signature);
mav.addObject("form", UploadViewModel.make("/content/general-import", "Updated content with file"));
return mav;
} else {
mav.addObject("form", UploadViewModel.make("/content/general-import", "Could not update content with file"));
return mav;
}
}
It delegates to the following method for processing:
protected void processFileZipEntry(MultipartFile file, String signature) throws IOException {
byte[] bytes = file.getBytes();
LOG.debug("Processing archive with bytes={}.", file.getBytes().length);
ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(bytes));
LOG.debug("Processing archive with size={}.", file.getSize());
ZipEntry entry = null;
while ((entry = zis.getNextEntry()) != null) {
LOG.debug("Processing file={} is directory?={}.", entry.getName(), entry.isDirectory());
// process each file, based on what it is and whether its a directory etc.
if (!entry.isDirectory()) {
// if the entry is a file, extract it
LOG.debug("Processing entry: {}",entry.getName());
int length = (int) entry.getSize();
Content contentToSave = null;
if(entry.getName().contains("gif")) {
contentToSave = Content.makeImage(entry.getName(), Content.GIF, signature, getBytesFrom(zis, "gif"));
} else if (entry.getName().contains("png")) {
contentToSave = Content.makeImage(entry.getName(), Content.PNG, signature, getBytesFrom(zis, "png"));
} else if (entry.getName().contains("jpeg")) {
contentToSave = Content.makeImage(entry.getName(), Content.JPEG, signature, getBytesFrom(zis, "jpeg"));
} else if (entry.getName().contains("json")) {
contentToSave = Content.makeFile(entry.getName(), Content.JSON, signature, getStringFrom(zis, length));
} else if (entry.getName().contains("js")) {
contentToSave = Content.makeFile(entry.getName(), Content.JS, signature, getStringFrom(zis, length));
} else if (entry.getName().contains("css")) {
contentToSave = Content.makeFile(entry.getName(), Content.CSS, signature, getStringFrom(zis, length));
}
Content contentAleadyThere = contentService.fetch(entry.getName());
if(contentAleadyThere != null) {
LOG.warn("Replacing file: {} with uploaded version.", contentToSave.getName());
}
contentService.put(contentToSave);
LOG.info("Persisted file: {} from uploaded version.", contentToSave.getName());
}
}
}
Basically, in this permutation, the file bytes are there, but there are no entries (zis.getNextEntry() does not exist. I can see that the zip file contains files, and the byte[] has about 3MB worth of stuff, so something must be going wrong with the streaming. Does anyone have a recipe for going from MultipartFile to ZipFile or ZipInputStream?
EDIT
To give you more information, I have a test harnass around this code, by using a MockMvc
#Test
public void testProcessingGeneralUpload() throws Exception {
Resource template = wac.getResource("classpath:lc_content/content.zip");
System.out.println("template content length: " + template.contentLength());
System.out.println("template path: " + template.getFile().getPath());
System.out.println("template filename: " + template.getFilename());
MockMultipartFile firstFile = new MockMultipartFile(
"file", "content.zip", MediaType.APPLICATION_OCTET_STREAM_VALUE, extractFile(template.getFile()));
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.fileUpload("/content/general-import")
.file(firstFile))
.andExpect(status().isOk())
.andExpect(view().name("contentUpload"))
.andExpect(model().attributeExists("form")).andReturn();
// processing assertions
ModelMap modelMap = mvcResult.getModelAndView().getModelMap();
Object object = modelMap.get("form");
assertThat(object, is(not(nullValue())));
assertThat(object, is(instanceOf(UploadViewModel.class)));
UploadViewModel addModel = (UploadViewModel) object;
assertThat(addModel.getMessage(), is(notNullValue()));
assertThat(addModel.getPostUrl(), is(notNullValue()));
assertThat(addModel.getPostUrl(), is("/content/general-import"));
assertThat(addModel.getMessage(), is("Updated content with file"));
// persistence assertions
assertThat(contentDao.findByName("/content/control/basket-manager.js"), is(notNullValue()) );
}
The extractFile method is as follows:
private byte[] extractFile(File zipFile) throws IOException {
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFile));
System.out.println("length of file: " + zipFile.length());
byte[] output = null;
try {
byte[] data = new byte[(int)zipFile.length()];
zipIn.read(data);
zipIn.close();
output = data;
} catch (IOException e) {
e.printStackTrace();
}
return output;
}
The length of bytes it produces is 3617817, which is the size I expect, and this is fed into the controller method at the top of this question.
I have continued working the problem. The size of the file is correct, it is a zipped file (it unpacks via the OS perfectly), and yet no ZipEntry enumeration.
I would for starters rewrite some of the code instead of doing things in memory with additional byte[].
You are using Spring's Resource class so why not simply use the getInputStream() method to construct the MockMultipartFile as you want to upload that file.
Resource template = wac.getResource("classpath:lc_content/content.zip");
MockMultipartFile firstFile = new MockMultipartFile(
"file", "content.zip", MediaType.APPLICATION_OCTET_STREAM_VALUE, template.getInputStream());
The same for your upload processing code the ZipInputStream can also be constructed on another InputStream which is also provided by the MultipartFile interface.
protected void processFileZipEntry(MultipartFile file, String signature) throws IOException {
LOG.debug("Processing archive with size={}.", file.getSize());
ZipInputStream zis = new ZipInputStream(file.getInputStream());
Wouldn't be the first time that jugling around with byte[] gives a problem. I also vaguely recall some issues with ZipInputStream which lead us to use ZipFile but for this you will first have to store the file in a temp directoy using the transferTo method on MultipartFile.
File tempFile = File.createTempFile("upload", null);
file.transferTo(tempFile);
ZipFile zipFile = new ZipFle(tempFile);
// Proces Zip
tempFile.delete();
Before making HttpConnection from blackberry application i want to check if it is open or not?. Because without checking that when i tried to make a connection i got class net.rim.device.api.io.ConnectionClosedException.
EDIT: Posted the code from the OP's answer.
Below is my code for the http connection.
public String makePostRequest(String[] paramName, String[] paramValue) {
StringBuffer postData = new StringBuffer();
HttpConnection connection = null;
InputStream inputStream = null;
OutputStream out = null;
try {
connection = (HttpConnection) Connector.open(this.url);
connection.setRequestMethod(HttpConnection.POST);
for (int i = 0; i < paramName.length; i++) {
postData.append(paramName[i]);
postData.append("=");
postData.append(paramValue[i]);
postData.append("&");
}
String encodedData = postData.toString();
connection.setRequestProperty("Content-Language", "en-US");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", (new Integer(
encodedData.length())).toString());
connection.setRequestProperty("Cookie", Constants.COOKIE_TOKEN);
byte[] postDataByte = postData.toString().getBytes("UTF-8");
out = connection.openOutputStream();
out.write(postDataByte);
DebugScreen.Log("Output stream..."+out);
DebugScreen.Log("Output stream..."+connection.getResponseCode());
// get the response from the input stream..
inputStream = connection.openInputStream();
DebugScreen.Log("Input stream..."+inputStream);
byte[] data = IOUtilities.streamToBytes(inputStream);
response = new String(data);
} catch ( Exception e) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
WaitingScreen.removePopUP();
Status.show(Constants.CONNETION_ERROR);
}
});
DebugScreen.Log("Exception inside the make connection..makePostRequest."
+ e.getMessage());
DebugScreen.Log("Exception inside the make connection..makePostRequest."
+ e.getClass());
}finally {
try {
if(inputStream != null){
inputStream.close();
inputStream = null;
}
if(out != null){
out.close();
out = null;
}
if(connection != null){
connection.close();
connection = null;
}
} catch ( Exception ex) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
WaitingScreen.removePopUP();
}
});
DebugScreen.Log("Exception from the connection2 class.."
+ ex.getMessage());
DebugScreen.Log("Exception from the connection2 class.."
+ ex.getClass());
}
}
return response;
}
Before making httpconnection from blackberry application i want to check if it is open or not.
That doesn't make sense. You want to make sure it is open before you open it. You can't. You have to try to open it, and handle the exception if it fails. That's what the exception is for.
The best way to test whether any resource is available is to try to use it. You can't predict that. You have to try it.
Because without checking that when i tried to make a connection i got class net.rim.device.api.io.ConnectionClosedException.
So it wasn't available. So now you know. That's the correct behaviour. You're already doing the right thing. There is no question here to answer.
I am having some troubles running an Xquery with Saxon9HE, which has a reference to an external module.
I would like Saxon to resolve the module with a relative path rather absolute.
the module declaration
module namespace common = "http://my-xquery-utils";
from the main xquery
import module namespace common = "http://my-xquery-utils" at "/home/myself/common.xquery";
from my java code
public class SaxonInvocator {
private static Processor proc = null;
private static XQueryEvaluator xqe = null;
private static DocumentBuilder db = null;
private static StaticQueryContext ctx = null;
/**
* Utility for debug, should not be called outside your IDE
*
* #param args xml, xqFile, xqParameter
*/
public static void main(String[] args) {
XmlObject instance = null;
try {
instance = XmlObject.Factory.parse(new File(args[0]));
} catch (XmlException ex) {
Logger.getLogger(SaxonInvocator.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex){
Logger.getLogger(SaxonInvocator.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.print(transform(instance, args[1], args[2]));
}
public static String transform(XmlObject input, String xqFile, String xqParameter) {
String result = null;
try {
proc = new Processor(false);
proc.getUnderlyingConfiguration().getOptimizer().setOptimizationLevel(0);
ctx = proc.getUnderlyingConfiguration().newStaticQueryContext();
ctx.setModuleURIResolver(new ModuleURIResolver() {
#Override
public StreamSource[] resolve(String moduleURI, String baseURI, String[] locations) throws XPathException {
StreamSource[] modules = new StreamSource[locations.length];
for (int i = 0; i < locations.length; i++) {
modules[i] = new StreamSource(getResourceAsStream(locations[i]));
}
return modules;
}
});
db = proc.newDocumentBuilder();
XQueryCompiler comp = proc.newXQueryCompiler();
XQueryExecutable exp = comp.compile(getResourceAsStream(xqFile));
xqe = exp.load();
ByteArrayInputStream bais = new ByteArrayInputStream(input.xmlText().getBytes("UTF-8"));
StreamSource ss = new StreamSource(bais);
XdmNode node = db.build(ss);
xqe.setExternalVariable(
new QName(xqParameter), node);
result = xqe.evaluate().toString();
} catch (SaxonApiException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static InputStream getResourceAsStream(String resource) {
InputStream stream = SaxonInvocator.class.getResourceAsStream("/" + resource);
if (stream == null) {
stream = SaxonInvocator.class.getResourceAsStream(resource);
}
if (stream == null) {
stream = SaxonInvocator.class.getResourceAsStream("my/project/" + resource);
}
if (stream == null) {
stream = SaxonInvocator.class.getResourceAsStream("/my/project/" + resource);
}
return stream;
}
}
If a change it into a relative path like
import module namespace common = "http://my-xquery-utils" at "common.xquery";
I get
Error on line 22 column 1
XQST0059: java.io.FileNotFoundException
I am not sure how the ModuleURIResolver should be used.
Saxon questions are best asked on the Saxon forum at http://saxonica.plan.io - questions asked here will probably be noticed eventually but sometimes, like this time, they aren't our first priority.
The basic answer is that for the relative URI to resolve, the base URI needs to be known, which means that you need to ensure that the baseURI property in the XQueryCompiler is set. This happens automatically if you compile the query from a File, but not if you compile it from an InputStream.
If you don't know a suitable base URI to set, the alternative is to write a ModuleURIResolver, which could for example fetch the module by making another call on getResourceAsStream().