Let's explain my graduation project then my question.
My graduation project is about compiling java code online.
To compile user's code, I am using java compiler api on background bean class. After compilation is finished .class file is generated on the D:\eclipse-jee-mars-R-win32-x86_64\eclipse directory. Then the progam saves input file that is writed in text area(in JSP) to D:\eclipse-jee-mars-R-win32-x86_64\eclipse directory. After creating input file, the program runs the code by using dos command at runtime and process getInput stream. The getInput stream returns output of the code. If entered code(user's code) creates any output file, output file will be generated also.
We suggest for users that "your code's output file name should be 'output.txt'".
If the user's code creates any output file. "output.txt" file is generated on D:\eclipse-jee-mars-R-win32-x86_64\eclipse directory.Then, the program retrieves 'output.txt' contents to JSP and show the "output" of their codes to users.
Thus far, there is no problem. Problem is starting here. For one user there is no problem but think for 2 users or more. If 2 or more users compile codes at the same time problems will occur because their .class .java and "output.txt" files will be the same file because for all users we creates same name file on D:\eclipse-jee-mars-R-win32-x86_64\eclipse directory. Maybe for all users, creating files as unique name will help me but it creates another problem. Our project also analyse codes by looking runtime of the codes. This solution[unique name] brings parallel working codes and analysis results will be unfair. Because sometimes 1 code is worked, sometimes 100 code is worked on the website.
I need to compile, execute, analyse codes one by one, not parallel.
How can I solve this problem? What a solution can be used for this situation?
"Accepting random code from the internet to compile/run it server-side" - this sounds like a particularly bad idea, opening you up for all kinds of nasty attacks. DOS (Denial of Service) being only one of them.
Further, the architecture to externally execute code and share a common well-known file - as you state - makes it impossible to execute more than one of these programs at the same time
Storing this external code in some IDE's directory is another weird thing to me.
In fact, I think that this whole architecture is such a bad idea that I have a hard time suggesting a solution other than to rethink it: If you have a very good reason for accepting random code from the internet (other than researching exactly this question), please state it here.
With protest (and the suggestion to not follow this tip) I'd point to the option to just pipe the application's console output (e.g. System.out) back to the client instead of that one single wellknown file. At least now you can safely be attacked by many users coming in parallel, without mixing up the replies.
I solved my problem with using synchronized block. It is enough for my project.
In project JSP file.
synchronized(this){
//my compilation, running and analysis part is here
}
Now, one thread can process this part. It means that, for thousands users all codes are processed one by one. No parallel working codes.
Related
I am maintaining a Spring Boot project. There is this code:
BufferedReader reader = new BufferedReader(new FileReader("./setting_mail_sender.txt"));
Where should the file be located in this case?
In 'the current working directory'. And where is that? Who knows!
Whomever wrote that code messed up. It's not a good idea to use the CWD for anything in any java code unless you specifically know you want it. And generally, that's only the case when you're writing command line tools in the vein of the various tools you find in your average linux distro's /bin dir - a rare occurrence, given that the JVM isn't really designed for that kind of thing.
There are 3 different best practices for 'data files' depending on the nature of the data:
Static, unchanging data - as much part of your app as your class files are. These should be loaded with MyClass.class.getResource("name-of-resource.txt") and shipped the same way your classes are. For example, inside the jar file.
Config files. These should usually be in System.getProperty("user.home") - the user's home dir; /Users/yourusername on macs, /home/yourusername on linux, C:\Users\YourUserName on windows. Best practice is to ship a 'template' version of the settings file if relevant in the jar file, and upon detecting that there is no config file present at all, to write out the template (and you load the template in via MyClass.class.getResource). If a template is not a good idea, something in a similar vein. Bad practice is to have the installer do this, and have your app be broken or leave the user having to peruse complex documentation to (re)create the config file. A different way to do it right is to have a config page in your app (a window, menu bar setting, web app thing - something with a user interface) where you can change settings and the config file is simply the way you store that data.
Changing data files. For example, you ship H2 (an all-java database engine) with your app and it needs to write its database file somewhere. This is a bit tricky; user home is not the right place for such data files, but you can't really 'find' the dir where your app is installed either. Even if you can, on non-badly-designed OSes, apps usually cannot (and should not!) be able to write to that location anyway. The location where this data is stored should definitely be configurable, so one easy way out is to require that the user explicitly picks a place. Otherwise I'm afraid you're stuck having to write per-OS code - find /Users/myusername/Library/Application Support/yourappname on mac, which is the right place. As far as I know there is no library to do this right.
None of them involve 'require that the user start the app with the right CWD'. There are good reasons for that: It can be hard to configure, and it's not something users think of to configure. For example, when setting up a java app as a recurring task in windows, you can configure the working dir for such a process, but it's not something that's usually considered as crucial configuration. When running a java app from the command line, who knows what the working dir is. You'll end up with an app that usually works, except in some circumstances when it magically doesn't, and most of your users have no idea that the difference between the magic run that works and the one that does not, is the directory they were in when they started the java app.
If you can edit that code, do so - figure out which of the 3 different kinds of data this is about (sounds like the second bullet: Config stuff, so should be in user home, and the app's name should be part of the file name) - and fix it. for example, that should be:
try (var in = Files.newBufferedReader(Paths.get(System.getProperty("user.home"), "myapp-mail.conf")) {
}
This solves a whole bunch of problems:
Uses try-with to avoid resource leakage.
Reads from user.home, avoiding current working directory as relevant setting.
Actually uses UTF-8 encoding (whereas your code will, at least until java 17, do 'platform default'. It's somewhat unlikely you want that, as it means your config file is not portable; copying it from one computer to another may break things. You presumably don't want this.
If errors occur, the error messages are improved (one of the downsides of the 'old' file API).
If you can't change this code, figure out what the CWD is; put the files there, and ensure that, however you start this spring boot project, you always start it from that directory. If you can't change this code but you can run some code in that JVM, you can print it: System.out.println(Paths.get(".").toAbsolutePath()) will show it to you.
This question is a little complicated but I will do my best to make it simple.
I have a program which I want to run multithreaded.
This is what the program does:
initializes an executable (commandline utility)
loads a file into the executable (files are provided from a data provider method)
sends commands to that executable based on the file which was loaded
parses the received responses from executable
writes results to a csv file
All this takes place in a single method.
However when running in multithreaded mode, everything runs fine except, all the results written to the csv file are wrong and out of order.
However when I added the keyword sychronized in the method declaration and run the program with multiple threads, the program works just fine.
public sychronized void run(Dataprovider data) {
...
}
However the program runs at the same speed as if I were running in single thread mode. How can I fix this? This is driving me nuts...
How can I run this program properly multithreaded?
I'm looking for ideas and/or guidance
Edit:
However when running in multithreaded mode, everything runs fine
except, all the results written to the csv file are wrong and out of
order.
I load a file in the executable, I run some calculations on that file, then save it. I then get the file size in bytes (file.length) for that newly generated file. I compare the results of that new file with the old file (file which was loaded) and I see that the new file is smaller than the old file (which is totally wrong). The file sizes for the new file is consistently 12263 bytes, which is incorrect
Edit:
Here is a partial code which does the writing to CSV file:
Edit:
Removing code example for simplicity
However when running in multithreaded mode, everything runs fine
except, all the results written to the csv file are wrong and out of
order.
I can make sore guesses as to what you mean by this statement, but it would help if it were more specific.
Is it the case that the results are wrong because outputs from different threads are being jumbled together into the same line or even the same token within a line?
In a csv file, the records are typically separated by newline characters. Can you refactor your solution so that a thread produces a complete line before writing to the output, and writes that line all in one go to the output?
Does your solution already do it that way? (It's not clear... there is no code in the question.)
I have to create a jar with a java application that fulfills the following features:
There are xml data packed in the jar which are read the first time the application is started. with every consecutive start of the application the data are loaded from a dynamically created binary file.
A customer should not be able to reset the application to its primary state (e.g. if the binary file gets deleted for some reason, the application should fail to run again and give an error message).
All this should not depend on the os it is running on (which means e.g. setting a registry entry in windows won't do the job)
Summarizing I want to prevent a once started application to be reset in order to limit illegitimate reuse of the application.
Now to my ideas on how to accomplish that:
Delete the xml from the jar at the first run (so far I came to the understanding that it is not possible to let an application edit it's own jar. is that true?)
Set a variable/property/setting/whatever in the jar permanently at the first run (is that possible)
Any suggestions/ideas on how to accomplish that?
update:
I did not find a solution for this exact problem, but I found a simple workaround: along with my software I ship a certain file which gets changed after the program is started the first time. of course if someone keeps a copy of the original file he can always replace it and start over.
Any user able to delete the binary file, will, with enough time, also be able to revert any changes made in the jar. When the only existing part of the application is in the hand of the user, you won't able to prevent changes to it.
You can easily just store a backup of the original jar, make a copy, use that for one run, delete, copy the original jar, etc. You would need some sort of mechanism outside the users machine, like an activation server. The user gets one code to activate an account, and can't use that code again.
I need to generate the test cases using white box testing..
I would like to share my idea of what we are doing and would also like you to give suggestions on it, if any, if we are going wrong.
As Netbeans and eclipse are having their own editors for writing java programs n then compile and generate test cases for the same..
But our aim is to create the application that accepts i.e reads java program written anywherei.e like notepad,command prompt i.e stored anywhere but should be .java file to be read by our application and our application should on reading the .java file should be directly able to generate the test cases for it.
What we have done is created some grammars for control statements i.e., for,if,switch,etc, have parsed the java file into tokens,and we are now in a process to create the symbol table to retrieve the symbols from user's java file consisting of symbol name,its length,value,data type.But we are stuck here..
Its getting difficult to retrieve symbols,its value and data type from java file..
Everything is coded in java,and no tool is used.Please provide some solution.
If I understood you correctly, this boils down to whether it's possible to generate test cases based on source code, and if so, how to do that. The short answer is that it's not. You can generate something, but it won't be testing anything useful. You should be designing test cases based on your requirements/specification, not your code.
Think of it this way: if your tests are based on the code, they have no frame of reference for what is correct or incorrect. As a result, the most they will be able to do is faithfully confirm that your code does whatever it is that your code does; they won't be able to compare to what the code is supposed to do.
I am developing a Java Desktop Application. This app needs a configuration to be started. For this, I want to supply a defaultConfig.properties or defaultConfig.xml file with the application so that If user doesn't select any configuration, then the application will start with the help of defaultConfig file.
But I am afraid of my application crash if the user accidentally edit the defaultConfig file. So Is there any mechanism through which I can check before the start of the application that whether the config file has changed or not.
How other applications (out in the market) deal with this type of situation in which their application depends on a configuration file?
If the user edited the config file accidentally or intentionally, then the application won't run in future unless he re-installs the application.
I agree with David in that using a MD5 hash is a good and simple way to accomplish what you want.
Basically you would use the MD5 hashing code provided by the JDK (or somewhere else) to generate a hash-code based on the default data in Config.xml, and save that hash-code to a file (or hardcode it into the function that does the checking). Then each time your application starts load the hash-code that you saved to the file, and then load the Config.xml file and again generate a hash-code from it, compare the saved hash-code to the one generated from the loaded config file, if they are the same then the data has not changed, if they are different, then the data has been modified.
However as others are suggesting if the file should not be editable by the user then you should consider storing the configuration in a manner that the user can not easily edit. The easiest thing I can think of would be to wrap the Output Stream that you are using to write the Config.xml file in a GZIP Output Stream. Not only will this make it difficult for the user to edit the configuration file, but it will also cause the Config.xml file to take up less space.
I am not at all sure that this is a good approach but if you want to go ahead with this you can compute a hash of the configuration file (say md5) and recompute and compare every time the app starts.
Come to think of it, if the user is forbidden to edit a file why expose it? Stick it in a jar file for example, far away from the user's eyes.
If the default configuration is not supposed to be edited, perhaps you don't really want to store it in a file in the first place? Could you not store the default values of the configuration in the code directly?
Remove write permissions for the file. This way the user gets a warning before trying to change the file.
Add a hash or checksum and verify this before loading file
For added security, you can replace the simple hash with a cryptographic signature.
From I have found online so far there seems to be different approaches code wise. none appear to be a 100 hundred percent fix, ex:
The DirectoryWatcher implements
AbstractResourceWatcher to monitor a
specified directory.
Code found here twit88.com develop-a-java-file-watcher
one problem encountered was If I copy
a large file from a remote network
source to the local directory being
monitored, that file will still show
up in the directory listing, but
before the network copy has completed.
If I try to do almost anything non
trivial to the file at that moment
like move it to another directory or
open it for writing, an exception will
be thrown because really the file is
not yet completely there and the OS
still has a write lock on it.
found on the same site, further below.
How the program works It accepts a ResourceListener class, which is FileListener. If a change is detected in the program a onAdd, onChange, or onDelete event will be thrown and passing the file to.
will keep searching for more solutions.