I was considering including the source code in my archive file (EAR, JAR, WAR) so we could see what the deployed application looks like.
This will obviously make the archive much bigger. Does the size of the archive file affect performance on the application server at all? Is this a good idea or not?
Here's another solution to your problem which can come instead (of putting the sources in the .jar) or in addition to it: Specify the source control revision id to the .jar. You can specify it in the manifest file or in a properties file.
The source control revision id is the current id associated with the root of your project on the source control system. It is readily available in SVN, Git and most modern source control systems. In older systems (CVS) you must first create a (named) tag probably by using current date and time (to ensure uniqueness). The revision number will let you to retrieve from the source control the exact snapshot from which the archive was obtained, so when you fix bugs you'll be fixing them on the correct sources.
This technique will allow you to save space - you won't need to ship the whole source directory.
However, it is still a good idea to specify this number even if the sources are included in the archive simply because it unanimously specifies the point in history where the archive was created. Manually comparing the sources in the archive with those in the source control is a pain.
It does affect the performance to the extent that there are more entries in the archive's index but that won't be too bad and you'll put the source in its own subdirectory. Or you can just make a source archive and shovel it around with the other files. That would be my choice. Of course if this is a GPL distribution, you'll have to be explicit about where the source is located.
Related
I have build a set of Java classes that act as kind of plugins in a third party application.
When ever new request come on my table I create new classes (plugins) or modify existing one.
To make the changes available to the third party application I can put a Jar into an so called extlib directory or put single class files into an so called ext directory.
I am looking for a proper way to handle different versions of my files.
When changing only one single class it a bad idea to replace all class files in ext dir. Same problem when compiling as JAR. After changing one single class, I would have to compile q whole new JAR with all files inside.
Replacing all files inherits the chance of accidentely replacing a untested change.
Do you have any hints / best practices of how I could manage the different file versions?
My Ideas:
Some kind of patch would be great. When changing some files, I just push a button to compile a zip archive with all changed files inside. In optimal case with a version mark in all the files.
Would something like this be possible with eclipse plugins pxe.?
There exist a number of workflows for this.
The terminology varies a bit depending on the version control system that you are using; I am going to use git terminology.
One workflow is to always work on a branch, and to never merge a branch that has not been thoroughly tested into master. So, then, a release is only made from master.
Another workflow is to work on whatever branch you want, merge into master whenever you want, then every once in a while pull from master into a designated "release" workspace, do your testing there, and then release from that.
As for binary patching, I am sure there exist tools out there, but I do not know of one, I asked a few people and they don't know either, so I have no answer for you here. I suppose if you have .class files you can use some folder synchronization tool, but if you have .jar files then you are going to be replacing them in their entirety.
We all know "inputable" resources are by convention in src/main/resources and src/test/resources, but what about the runtime outputted ones? Is it better to use target/ or target/{classes,test-classes}or simply give up and try to use external path even if it complicates things for security reasons? I've been brainstorming a bit regarding that decission as shown following, but need the help of more experienced users that can shed more light.
PROS of target/{classes, test-classes}
If maven engineers architected the convention by moving resources to target/classes instead of target/resources I assume they had a good reason in mind for preferring it
It organizes input and output resources on the same base folder
It makes test and main outputs independent, so no conflict can appear if names are equal
IT makes much conventional and secure to define the relative route of the resource ( by ClassLoadeR().getResource() or etProtectionDomain().getCodeSource().getLocation() [no file globs]
It makes much easy to centralize output behavior, in case our idea is having a function for UPSERTing resources, we need to use resolution for sufolder as they are not in the same path (so prepend /classes/ to the relative route but / for an original resource)
I think due to the previous ones, there can be a bit of confusion when using parent poms, because there is a target for both parent and module, but only one classloader URL -> /target/classes
It works flawlessly if using the classes directory as the base classpath of the app, when executing directly from console.
PROS of target/
When packaging the app as a library, you don't need to deal with an output folder inside the jar.
I have been told that maven doesn't like too much anything strictly outside of target/, but have no further info
A central folder can be used when executing tests in case production code generates files and tests works with them also
Perhaps a single target at parnet pom's level makes files easier to share among different modules
So how do you usually handle these sort if things?
I am sure some of you have a more authoritative question
So typically if you are allowing resources to be pulled in from outside of your Jar you need to either hard-code that relative path or read it from fixed config file. You would then document this when you release your application.
For example, Eclipse has a folder specially for plugins. You can drop new plugins here and know that Eclipse will pick them up and know what to do with them.
In my applications, I usually define a conf directory that sits at the same level as the executable Jar. I'll put any log4j and other such post-compile config files there.
You mention security issues, which is a good thing to think about. When you are pulling in data, always try to do some sort of sanity checking (make sure a directory exists, a zip file isn't corrupt, etc). Since you can't control what comes in, make sure you do as many checks as you can on the program side.
We have an java application in which the user can write/execute their own java code and use imports from compiled jars - i.e. they write it, and it is compiled and run by the application. They can also save this code (along with various other information that they are using) - currently this is saved to a human-readable xml file.
I want to be able to use those save xml files in an IDE (principally, Intellij), so that if the user changes things in their compiled jar in the IDE, these changes can also be picked up in the save xml file.
For example, if a save file used a class from the compiled jar, it may have the following import:
import com.company.project.package.subpackage.MyClass;
Let's say that class was moved, so the import was:
import com.company.project.package.subpackage.subsub.MyClass;
...this would change all the save xml files that used that class and import - just as the IDE would for all the other usages in the compiled project.
(This, and other examples, arises because the compiled jar is both constantly in development and in use using the aforementioned application.)
At the moment, if I were to add the save xml files to a sub-project in the IDE, the user can edit the save files manually, possibly taking advantage of 'find/replace' or 'search for usage in text' functions. This is better than nothing, but still a rather involved/complicated process. Also, there is no checking that the code in the save files are consistent with the code in the compiled project.
One approach that I am considering is a script or a test class that would unpack the save xml file, writing the java code to java files, and then try and compile (and possibly running/testing) those java files.
A further step would be to write a maven plugin (we use maven for our build cycle) or an ant script (ant still has its uses...) to do this, and possibly make this part of our build process - i.e. you cannot compile the project without ensuring all of the save xml files in its sub-project also compile.
Does this seem like a reasonable approach?
Are there alternative approaches that anyone could suggest?
..saving as a .java file is not the solution I'm looking for.
Save it as a Zip with 1 (or more) XML files as well as any source (in paths according to package) that is required. You could even include other files easily, a manifest, help files etc.
This has a number of advantages:
It allows source & include files to be a different encoding to the XML
It consolidates all the necessary parts of the project into one file, without any 'jumping though hoops' to make one format fit inside another.
It allows different compression levels as appropriate to the data (e.g. text/XML compresses well, whereas a serialized image does not).
Is it possible to get installed Minecraft version using Delphi?
The interesting part is that I need to read the
%appdata%\.minecraft\bin\minecraft.jar version.But without META-INF\MANIFEST.MF reading.
A Java program doesn't have a version unless it's specified in the Manifest file.
Maybe the developer left the version number in some readme text file or some other resource inside of the JAR file, which, as you know, is just a ZIP archive.
If none of those work, an alternative would be to build a catalog of Minefield versions, based on the file size. Use the System FileSize() function to get the file size of the JAR file and look it up in your catalog.
Depending on the circumstances, if the file size is not found in your catalog, you may be able to assume that it's newer than the latest version you have cataloged.
Even better than relying on the file size for you catalog would be to generate a hash. Even CRC32 would be sufficient.
I believe JAR files are actually just ZIP files, and I heard recent versions of Delphi have a unit with tools to access Zip files. I'm not familiar with the internal structure of JAR files, but if you are, and the version info you're looking for is present somewhere, you should be able to extract it this way.
Yes, it is possible. You can use this xml data provided by mojang.
For example:
<Contents>
<Key>11w47a/minecraft.jar</Key>
<LastModified>2011-11-24T13:20:06.000Z</LastModified>
<ETag>"2ad75c809570663ec561ca707983a45b"</ETag>
<Size>2242242</Size>
<Owner>...</Owner>
<StorageClass>STANDARD</StorageClass>
</Contents>
As you can see they provide version and file name in the <Key> tag. The md5 sum of the binary is stored in <ETag> tag. As long as you haven't modified your jar this should be enough to check the version.
How do I clean up stale .class files out of ${workdir} given set of existing .java files in ${srcdir}? By stale I mean .class files that were generated from now removed .java files. I have tried coming up with something using Ant mappers and filesets etc. but I failed. Removing all .class files older than their respective source .java files would be acceptable, too.
I'm pretty sure there's an ant task to kill .classes older than the .java...
Depend sounds close, and may actually do what you want, but this isn't its intended purpose. Given developmentalinsanity's answer however, this may be the only thing that will Actually Work.
The problem is determining whether a class file without an obviously corresponding source file is really stale.
Try this in a single file (A.java)
public class A{}
class B{}
This will result in both A.class and B.class. So, B.class would seem stale because of the missing java file. You'd probably get similar issues with any inner classes.
Safest bet if you want to make sure there's no old class files lying around would be just to delete them all.
As it’s just not possible to detect what’s stale and what’s not, most builds have a clean target (that’s also part of cleanbuild). The clean target, just removes all files from you’re build directory. This directory normally is unversioned (svn:ignore).
Not all files in you’re build will be the result of the compiler, for example .property files, these files can be stored in an alternative directory that will be copies in to the build directory. For example in a web application build you can store those files in /web/WEB-INF/classes and let Ant copy them into the build directory.