parsing vagrant file inside java - java

I need to parse the configurations defined in a Vagrantfile written in Ruby and use the settings elsewhere in my java code. Tried exploring jRubyParser but din't come across any documentation that defines it's use.
Cloned the Vagrant repo locally, but browsing through the code does not help either as I don't have prior experience with Ruby. How would Vagrant be reading the configurations defined in the file ? Any inputs ?

Vagrantfile is a regular Ruby script, i.e. it's meant to be interpreted by Ruby intepreter more than read as a configuration file.
To make things harder, some configuration options aren't declared as top level variables in Vagrantfile, but rather as properties of object in some function calls (like "config.vm.provider".
Depending on how complex your configuration is, I would consider just reading the file line by line and do regular expression matching to get variables I'd need. Not the most elegant solution, but probably way quicker too implement than alternatives.
Also, if your provider is always the same, say VirtualBox, maybe you could get some of your configuration from there. In that case, you would just need to read file located somewhere in "VirtualBox VMs" directory (on Mac, it's in "$HOME/VirtualBox VMs"). It's an XML file, so you could use one of the Java XML parsers to get what you need.

Related

Using Java to modify AWS file?

I would like to build a centOS 7 instance on AWS and install Apache to build web server.
After that, I would like to modify the config file, /etc/hosts and /etc/httpd/conf.d/test.conf where test.conf is created by me.
Can I use java to modify the file directly? Or I should create the file and replace the old file on instance? I am little bit confused for the feasibility. Please someone help.
There seem to be a few questions here, so I've split them out.
Q: Can I use programming language X to modify a file on the local filesystem?
A: Yes, with very few exceptions. For Java, yes (if the instance has a JRE).
Q: Should I use Java?
A: Probably not the first choice (you could probably do what you need in a shell script at launch).
Q: Should I create the Apache config files dynamically or build them into an AMI?
A: Difficult to answer without more information. There are pros and cons to AMIs. If it's simple and quick to create/modify the files on launch, then I'd do it that way.
DevOps is a big subject and there are many options available to you for bootstrapping EC2 instances. Pre-baked AMIs is one option. Another simple option that you might consider is to write userdata scripts, that run at launch time, and that set up the instance for you (see simple nginx example). They can install software, modify config files, start services, and other things. They can also pull collateral such as pre-staged config files from S3, which can be a handy option.

Symbol to signify the root of a project

Is there a well accepted symbol in the programming world for the root of a project?
For example, the tilde ~ is the user's home directory, but this not just convention, but part of UNIX.
I am looking for a symbol that is merely convention.
If you are looking for a convention for use in communicating with a team, I'd suggest the project name followed by a /. This makes it clear as to what project you are referring to. If the project name is already implied by the context, it seems to be the convention to simply use a subdirectory name, with or without a trailing slash. See here and here for examples from Linux-kernel related documentation.
I'm not aware of any such convention. In Autoconf, variables top_srcdir and abs_top_srcdir points to the root of a project. In git, this does the job:
git rev-parse --show-toplevel
However, if you are looking for a single character symbol, I suggest borrowing the tee character: ⊤ (U+22A4, &#8868). I don't think it has ever been used for that, but it captures the idea of top.
the root of a project
What means the root of the project exactly ? Given which context ? Which types of projects ? Are you talking about a deployed web projects ? A source tree of a web projects ? A command line utility written in C ? Or in Java ? Or Go ?
Each language and framework provides its on sets of predefined structures to follow. The root of the project is then, either the root of the vcs, which may store many assets not strictly related to the business of the software, or the root according to the given framework / language you are working with, in which case, i assume it is safe to say, it can be anything because they are so many different fw for so many different concerns.
Windows vs. POSIX
The Portable Operating System Interface (POSIX) like UNIX.
Windows has C:// or other drivers as root, while POSIX have / as root.
to know if the file is a root path or not, you can use path.isAbsolute('PATH_HERE') this ill return true if it is a root path.
to know if your node is running on a windows or POSIX platform use process.platform
to check if you are running in windows:
var isWin = /^win/.test(process.platform);
nodeJS Docs: https://nodejs.org/dist/latest-v6.x/docs/api/path.html#path_path_isabsolute_path
i think people usually use label to be the root instead of symbol, e.g., /server for the root of node app.
The Be-all, End-all
After doing the bare minimum of research and reading about 1/4 of a wikipedia article on Root Directory I have come to the almighty, forever-binding conclusion that:
No, there is no standardized way of indicating you are in the root directory of an arbitrary project. (Apart from reading the path itself)
Here is another link pertaining to inodes farther down to make it seem like I did more research.
In that case, making a standard seems like fun doesn't it?
The standard you come up with doesn't have to be global, it can just apply to your dev team if you want it to. In that case, let's make 3 right off the top of our (my) head.
How about |->foo/bar/a.java? The | indicates a flat level, with nothing before it.
We could always try a boring (but useful... I guess): (foo)/bar/a.java
Or to spice things up a little bit, we could do...
I am gROOT
|foo|/bar/a.java
Whatever standard you choose (which is kinda funny, because the usage of standard implies that there's only one) you're now going to have to...
Implement it!
This is going to be the hard part. You're going to have to find some way to indicate to the OS that you're not only in an arbitrary directory, but that you're in a directory that holds slightly more significance than others. Maybe you add another section to the INODE (in *nix at least) that specifies that it's important. Maybe you don't fuss around with all the OS level stuff, and instead patch git to recognize the root of all git projects... which now that I think about it, kind of already happens.
Possible Implementation
Lets use git as an example. Git projects are denoted by .git files in the root directory. So let's take that a step farther and put a .base file in every directory that is the root of a project (or what have you). The .base doesn't even need to have anything in it, it just needs to be there. Now, patch up whatever terminal you're using to recognize the .base file as the root of an arbitrary project, and display it however you like! EZ-PZ
Possible additions?
Some other thoughts here, maybe you could add some configuration to the .base file, like so:
proj_name=WorldTraveller
lang=java
other=stuff
can=go
here=whatever
which then drives how its displayed in the terminal. The above configuration using my first suggested standard would be
|->WorldTraveller/Countries/France/a.java
Note
I'm not trying to come off as a sarcastic D.i.a.B, so if I came off as one it wasn't my intention. I like to have fun answering questions sometimes.

Reading Java properties files in Hadoop MapReduce applications

I was wondering what is the standard practice for reading Java properties files in MapReduce applications and how to pass the location to it when submitting (starting) a job.
In regular Java applications you can pass the location to the properties file as a JVM system property (-D) or argument to main method.
What is the best alternative (standard practice) for this for MapReduce jobs? Some good examples would be very helpful.
The best alternative is to use DistributedCache, however it may not be the standard way. There can be other ways. But I haven't seen any code using anything else so far.
The idea is to add the file to the cache, and read it inside setup method of map/reduce and load values into a Properties or a Map. If you need snippet I can add.
Oh I can remember, my friend JtheRocker used another approach. He set entire contents of the file against a key in the Configuration object, got it's value on setup then parsing & loading the pairs in a Map. In this case, file reading is done on the driver, which was previously on the task's side. While it's suitable for small files and seems cleaner, orthodox people may not like to pollute conf at all.
I would like to see, what other posts bring out.

Patching Java software

I'm trying to create a process to patch our current java application so users only need to download the diffs rather than the entire application. I don't think I need to go as low level as a binary diff since most of the jar files are small, so replacing an entire jar file wouldn't be that big of a deal (maybe 5MB at most).
Are there standard tools for determining which files changed and generating a patch for them? I've seen tools like xdelta and vpatch, but I think they work at a binary level.
I basically want to figure out - which files need to be added, replaced or removed. When I run the patch, it will check the current version of the software (from a registry setting) and ensure the patch is for the correct version. If it is, it will then make the necessary changes. It doesn't sound like this would be too difficult to implement on my own, but I was wondering if other people had already done this. I'm using NSIS as my installer if that makes any difference.
Thanks,
Jeff
Be careful when doing this--I recommend not doing it at all.
The biggest problem is public static variables. They are actually compiled into the target, not referenced. This means that even if a java file doesn't change, the class must be recompiled or you will still refer to the old value.
You also want to be very careful of changing method signatures--you will get some very subtle bugs if you change a method signature and do not recompile all files that call that method--even if the calling java files don't actually need to change (for instance, change a parameter from an int to a long).
If you decide to go down this path, be ready for some really hard to debug errors (generally no traces or significant indications, just strange behavior like the number received not matching the one sent) on customer site that you cannot duplicate and a lot of pissed off customers.
Edit (too long for comment):
A binary diff of the class files might work but I'd assume that some kind of version number or date gets compiled in and that they'd change a little every compile for no reason but that could be easily tested.
You could take on some strict development practices of not using public final statics (make them private) and not every changing method signatures (deprecate instead) but I'm not convinced that I know all the possible problems, I just know the ones we encountered.
Also binary diffs of the Jar files would be useless, you'd have to diff the classes and re-integrate them into the jars (doesn't sound easy to track)
Can you package your resources separately then minimize your code a bit? Pull out strings (Good for i18n)--I guess I'm just wondering if you could trim the class files enough to always do a full build/ship.
On the other hand, Sun seems to do an okay job of making class files that are completely compatible with the previous JRE release, so they must have guidelines somewhere.
You may want to see if Java WebStart can help you as it is designed to do exactly those things you want to do.
I know that the documentation describes how to create and do incremental updates, but we deploy the whole application as it changes very rarely. It is then an issue of updating the JNLP when ready.
How is it deployed?
On a local network I just leave everything as .class files in a folder. The startup script uses robocopy or rsync to copy from network share to local. If any .class file is different it is synced down. If not, it doesn't sync.
For non-local network I created my own updater. It downloads a text file of md5sums and compares to local files. If different it pulls file down from http.
A long time ago the way we solved this was to used Classpath and jar files. Our application was built in a Jar file, and it had a launcher Jar file. The launcher classpath had a patch.jar that was read into the classpath before the main application.jar. This meant that we could update the patch.jar to supersede any classes in the main application.
However, this was a long time ago. You may be better using something like the Java Web Start type of approach, which offers more seamless application updating.

Possible ways to abstract away hard-coded path-names for properties file in java app

I'm trying to bind in a third party app to our project but have discovered that the unix paths of their property files have been hard-coded into several classes. It is probably possible to make minimal changes to their setup, so my question is: what are the possible (and quickest) ways to achieve this? The third party app uses neither ant nor spring, but just a build script that compiles the code into a .jar that is called from the command line.
You could read the properties files as resources. Then you only have to put the directories containing these files into your classpath.
You haven't actually said what you want to achieve. Would your application determine some paths and pass them to third party app via an API? Would something in your environment (for example a command line argument) specify the location of the files?
I would first refactor their code so that I know for certain that any hard coded strings are held in one defined place. So if for example they have
readProperties("/usr/thing/propertyFileXxx.txt");
or
static final String PROPERTY_XXX = "/usr/thing/propertyFileXxx.txt";
readProperties(PROPERTY_XXX);
I would first consolidate to a single accessor for the properties
readProperties(PROPERTY_XXX_ENUM);
So now we have a well-defined single piece of code that determines where to obtain the properties of each type and a specific list of the types of properties.
Then we need some controllable way to define the set of property files to be used at run-time. I have used the idea suggested by #tangens of loading the properties as resourcees from a specific directory added to the classpath.

Categories