I'm using SVNKIT 1.8 with SVN 1.8.5 and the SVN protocol to attempt to add files in bulk to my SVN repository. I would like to have one method for adding and updating files and the below code successfully handles both when using the FILE protocol since the editor.addFile(file, null, -1) throws an SVNException. When I switch to the SVN protocol (desired protocol), the editor.addFile(file, null, -1); doesn't throw an exception. Instead the editor.closeEdit(); throws an exception which is not desired. Any ideas on how to use one API for both adding and updating files?
public void addFiles(Map<String, String> data) throws Exception {
TreeSet<String> filesToCreate = new TreeSet<String>(data.keySet());
SVNRepository repo = null;
ISVNEditor editor = null;
try {
repo = openSession();
editor = repo.getCommitEditor("Adding files.", null);
editor.openRoot(-1);
for (String file : filesToCreate) {
try {
editor.addFile(file, null, -1);
} catch (SVNException e) {
editor.openFile(file, -1);
}
editor.applyTextDelta(file, null);
SVNDeltaGenerator gen = new SVNDeltaGenerator();
String checksum = gen.sendDelta(file, new ByteArrayInputStream(data.get(file).getBytes()), editor, true);
editor.closeFile(file, checksum);
}
editor.closeEdit();
} catch (Exception ex) {
abort(editor);
throw new Exception(ex.toString(), ex);
} finally {
closeSession(repo);
}
}
This is a side effect of an optimization in the svn:// protocol. During an editor drive the server does not send any response unless there is an error and as such the client can't tell that a specific action succeeded. I haven't looked at SVNKit's code but I'd bet that you could potentially get the exception from any of the editor methods since the error will be detected in the next editor drive call after the server responds. In this case your changes are so small that the editor drive sending happens before the response from the server can be detected and so you end up seeing the error when you do closeEdit().
The svnmucc command in Subversion has a similar problem as what you're trying to solve. It has a put operation that adds or updates a file. It uses the same technique that Dmitry advised you to use on the svnkit-users mailing list (link1, link2). Specifically running a check_path before determining to add or create the file.
You're not going to be able to do anything better than this because of the way the protocol works.
Related
I am still searching around this subject, but I cannot find a simple solution, and I don't sure it doesn't exist.
Part 1
I have a service on my application that's generating an excel doc, by the dynamic DB data.
public static void
notiSubscribersToExcel(List<NotificationsSubscriber>
data) {
//generating the file dynamically from DB's data
String prefix = "./src/main/resources/static";
String directoryName = prefix + "/documents/";
String fileName = directoryName + "subscribers_list.xlsx";
File directory = new File(directoryName);
if (! directory.exists()){
directory.mkdir();
// If you require it to make the entire directory path including parents,
// use directory.mkdirs(); here instead.
}
try (OutputStream fileOut = new FileOutputStream(fileName)) {
wb.write(fileOut);
fileOut.close();
wb.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Part 2
I want to access it from the browser, so when I call it will get downloaded.
I know that for the static content, all I need to do is to call to the file, from the browser like that:
http://localhost:8080/documents/myfile.xlsx
After I would be able to do it, all I need is to create link to this url from my client app.
The problem -
Currently if I call to the file as above, it will download only the file which have been there in the compiling stage, but if I am generating a new files after the app is running the content won't be available.
It seems that the content is (as it's called) "static" and cannot be changed after startup.
So my question is
is there is a way to define a folder on the app structure that will be dynamic? I just want to access the new generated file.
BTW I found this answer and others which doing configuration methods, or web services, but I don't want all this. And I have tried some of them, but the result is the same.
FYI I don't bundle my client app with the server app, I run them from different hosts
The problem is to download the file with the dynamic content from a Spring app.
This can be solved with Spring BOOT. Here is the solution as shown in this illustration - when i click Download report, my app generates a dynamic Excel report and its downloaded to the browser:
From a JS, make a get request to a Spring Controller:
function DownloadReport(e){
//Post the values to the controller
window.location="../report" ;
}
Here is the Spring Controller GET Method with /report:
#RequestMapping(value = ["/report"], method = [RequestMethod.GET])
#ResponseBody
fun report(request: HttpServletRequest, response: HttpServletResponse) {
// Call exportExcel to generate an EXCEL doc with data using jxl.Workbook
val excelData = excel.exportExcel(myList)
try {
// Download the report.
val reportName = "ExcelReport.xls"
response.contentType = "application/vnd.ms-excel"
response.setHeader("Content-disposition", "attachment; filename=$reportName")
org.apache.commons.io.IOUtils.copy(excelData, response.outputStream)
response.flushBuffer()
} catch (e: Exception) {
e.printStackTrace()
}
}
This code is implemented in Kotlin - but you can implement it as easily in Java too.
using java 8, tomcat 8
Hi, i am loading a file using properties, but i have a check before loading which returns the same properties object if its already been loaded (not null). which is a normal case scenario but i want to know if there is any way that if any change occur in target file, and some trigger should be called and refreshes all the properties objects. here is my code.
public static String loadConnectionFile(String keyname) {
String message = "";
getMessageFromConnectionFile();
if (propertiesForConnection.containsKey(keyname))
message = propertiesForConnection.getProperty(keyname);
return message;
}
public static synchronized void getMessageFromConnectionFile() {
if (propertiesForConnection == null) {
FileInputStream fileInput = null;
try {
File file = new File(Constants.GET_CONNECTION_FILE_PATH);
fileInput = new FileInputStream(file);
Reader reader = new InputStreamReader(fileInput, "UTF-8");
propertiesForConnection = new Properties();
propertiesForConnection.load(reader);
} catch (Exception e) {
Utilities.printErrorLog(Utilities.convertStackTraceToString(e), logger);
} finally {
try {
fileInput.close();
} catch (Exception e) {
Utilities.printErrorLog(Utilities.convertStackTraceToString(e), logger);
}
}
}
}
the loadConnectionFile method executes first and calls getMessageFromConnectionFile which has check implemented for "null", now if we remove that check it will definitely load updated file every time but it will slower the performance. i want an alternate way.
hope i explained my question.
thanks in advance.
Java has a file watcher service. It is an API. You can "listen" for changes in files and directories. So you can listen for changes to your properties file, or the directory in which your properties file is located. The Java Tutorials on Oracle's OTN Web site has a section on the watcher service.
Good Luck,
Avi.
I'm using the following code to dynamically generate a download in Wicket, using the ResourceLink approach (since the download is not a static file, it needs to be generated on the fly, and I was told this was the correct approach):
IResource res = new AbstractResource() {
#Override
protected ResourceResponse newResourceResponse(Attributes attributes) {
ResourceResponse resourceResponse = new ResourceResponse();
resourceResponse.setContentType("application/pdf");
resourceResponse.setFileName("output.pdf");
resourceResponse.setContentDisposition(ContentDisposition.ATTACHMENT);
resourceResponse.setWriteCallback(new WriteCallback() {
#Override
public void writeData(Attributes attributes) throws IOException {
OutputStream outputStream = attributes.getResponse().getOutputStream();
try {
outputStream.write(generateDocument());
} catch (Exception e) {
//Generation failed... Here I'd like to either show a popup message or alter the current page to show an error somewhere in the page
}
}
});
return resourceResponse;
}
};
ResourceLink<Void> resLink = new ResourceLink<Void>("resLink", res);
myForm.add(resLink);
The comment in the code above shows where I'm having trouble. If the generation of the download fails (which can happen, if certain conditions are not met) I'd like to show an error message, either by showing a popup or altering the page to show some error text (but in either case I want to avoid leaving/reloading the entire page)
Is this possible?
Here's the link with the answer:
https://cwiki.apache.org/confluence/display/WICKET/AJAX+update+and+file+download+in+one+blow
Don't forger to use a try/catch with an error(e.getMessage()) inside the catch and a target.add(feedbackPanel) after catching the error.
I am not sure this is possible because you need to use non-Ajax request to be able to download as ATTACHMENT. But since it is non-Ajax request you will need to either reload the current page or redirect to another page in case of an error.
We have a legacy system that has a admim module that allows users to upload jar files. After the upload, the jar file is validated and if not compliant to internal rules, it is deleted.
The problem is that windows is throwing an exception telling that the file "is already being used by another process." (when I call Files.delete(tmpJar);). I'm not able to identify why the file is open. Seems to me that I have closed everything.
First, we are using primefaces (4.0) to upload the file. Primefaces relies on commons-fileupload (1.3.1). It call the following method:
public void handleFileUpload(FileUploadEvent event) {
Path tmpJar = null;
try {
tmpJar = Files.createFile(Paths.get(event.getFile().getFileName()));
Files.write(tmpJar, event.getFile().getContents());
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
if (tmpJar != null) {
try {
this.validateJar(tmpJar.toString());
Files.delete(tmpJar);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
}
Before NIO Files.write, I was using "standard" java IO classes. The problem isn't related to the above code, because if I comment the call to validateJar, Files.delete(tmpJar) is executed without problems and the file is removed. So, the problem is related with the code below, but I can't find where...
Job is an internal class, basically a simple POJO. "jobAnnotation" is a custom annotation to identify Jobs. I have shortened the code, but the essencial parts are preserved.
private List<Job> validateJar(final String jarPath) throws IOException {
List<Job> jobs = new ArrayList<Job>();
try (JarFile jarFile = new JarFile(jarPath)) {
URL[] jars = { new URL("file:" + jarPath) };
ClassLoader jobClassLoader = URLClassLoader.newInstance(jars, this.getClass().getClassLoader());
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String className = jarEntry.getName();
Class<?> classToLoad;
try {
classToLoad = Class.forName(className, true, jobClassLoader);
} catch (Exception e1) {
LOGGER.error(e1.getMessage(), e1);
continue;
}
if (classToLoad.isAnnotationPresent(jobAnnotation)) {
String vlr = null;
try {
Class<?> jobClass = (Class<?>) Class.forName(classToLoad.getCanonicalName(), true, jobClassLoader);
Annotation annotation = jobClass.getAnnotation(jobAnnotation);
Method method = annotation.getClass().getMethod("getValue");
vlr = ((String) method.invoke(annotation, new Object[0]));
} catch (Exception e1) {
LOGGER.error(e1.getMessage(), e1);
}
Job job = new Job();
job.setEnabled(true);
job.setJarfile(jarPath);
job.setClassName(classToLoad.getName());
Parameter parameter = new Parameter();
parameter.setRequired(true);
parameter.setName("name");
parameter.setValue(vlr);
job.addParameter(parameter);
jobs.add(job);
}
}
} catch (IOException e) {
throw e;
}
return jobs;
}
Before using try-with-resources, I was using regular try-catch-finally to close the JarFile, thats the only thing that has a explicit close method. Probably is the classloading that is holding the file open, but I don't know how to close it.
I did some searches, and I found that I can't unload classes (Unloading classes in java?).
So, the problem is, how do I release it? Or how can I remove the file?
BTW, I'm using java 1.7.0_71, jboss 7.1.1, windows 7 (64).
The URLClassLoader class already has a close() method. The close() method will close any Jar file that are opened with the URLClassLoader. This should prevent the "file already in use" exception.
File is already being used by another process. says that it could be not your fault, maybe just another application is used that file. You can check this question to find a process which is used your file.
Some Virus scanner software take a long time in checking JARs. Try to disable the Virusscanner. Other candidates can be the Windows indexer process, or the explorer.exe itself. When you don't find any reason for the file lock, try a delay between the validation and the deletion. Maybe you need a loop with multiple tries.
Right now I am working on a android app and I am totally new to this.
I want to make sure my web-service is only accessible via my app.
My background is PHP. In PHP I don't need to worry about anything like that, because everything runs on a server.
In case of Java and especially Android programming things are different. Even with encryption. Everybody can just open an APK and see how the web service gets accessed. So is there a way to hide or to obfuscate the access to a web service, so only my app will be able to use it?
For test purposes I didn't add any security or encryption. This is the basic call to a web server I am doing right now:
String url = "http://thisismyurl.com/a.php?action=get";
String result = Web.executeWeb(url);
public class Web {
public static String executeWeb(final String url) {
final StringBuilder sb = new StringBuilder();
Thread thread = new Thread(new Runnable() {
public void run()
{
try
{
InputStream is = (InputStream) new URL(url).getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String result, line = reader.readLine();
result = line;
while((line=reader.readLine())!=null){
result+=line;
}
sb.append(result);
//System.out.println(result);
//Log.i("My Response :: ", result);
} catch (Exception e)
{
// TODO: handle exception
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sb.toString();
}
}
How would I hide this from the prying eyes of hackers? ;-) Is that even possible?
Thanks in advance!
Deploy client authentication using (self signed) certificates within TLS.
This kind of configuration can be enabled on most web servers and Java application servers, and you can normally also configure the web or application server in such a way that you can retrieve the certificate of the private key that the client used to authenticate itself.
Note that HTTPS uses SSL (or now TLS) before any web trafic, so you cannot program this in your application, it does require server configuration.
Check this link on how to configure for Apache 2.
Use your Application's ID ( like IMEI ) as parameter in your webservice call. You need to make a table in database at server side which will store all registered device. Now only these registered device can access your webservice. This is my idea, there should be other idea as well.