I have a GWT project which has its source managed in SVN, is packaged using Maven and has its builds managed via Hudson. I want to get the SVN revision number of the latest check-in/build to be visible in a comment at the bottom of the application root HTML file. I don't care where in the development process this happens!
Here are the options I've Googled for so far, with no success:
Can I get Hudson to, after building, write the build/revision number
to one of its build output files (namely the application root HTML
file)? I've seen no way to do this.
Can I get Maven to write the SVN revision number to one of its build
output files (namely the application root HTML file)? I've seen ways
of Maven writing this to a JAR/WAR manifest file (which can then be
accessed in the Java code), but I'm not sure that this works in GWT
(I'm not particularly knowledgeable about the internals of GWT).
Can I get SubVersion to, as a pre-commit hook, write the version number to a particular file? I know it's easy to write the version number to the file you're editing, but not so sure about writing to a totally separate file (so that it's updated on every commit, regardless of whether it was changed in that commit).
Does anyone have a complete, end-to-end example of how to get any of these working? I keep finding little snippets of code/config which do one part of the job, but not anything that is exactly what I'm looking for.
Thanks!
You can achieve what you're looking for with a combination of Maven and Hudson. In this example let's imagine you want the file version.txt at the root of your web app to contain the revision.
version.txt:
${SVN_REVISION}
In your project's pom.xml enable filtering in the maven-war-plugin:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<webResources>
<webResource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
<includes>
<include>version.txt</include>
</includes>
</webResource>
</webResources>
</configuration>
</plugin>
Make sure that Hudson is building your project via. Subversion checkout and it will set the SVN_REVISION environment variable for every build and Maven will fill it in.
This solution is for those who keep getting {SVN_REVISION} instead of the actual SVN_REVISION value inside the target file.
My solution was to also use filtering. However since I wanted the SVN_REVISION to appear inside my gwt app's main html page (as a means of "fighting" the user's cache, making sure that if we carry out a new build, then the user downloads the latest html file), I wasn't able to use Jason Terk's solution. The html file simply printed {SVN_REVISION} instead of the actual SVN_REVISION value.
So I defined a property inside <properties>:
<properties>
...
<buildVersion>${SVN_REVISION}</buildVersion>
...
</properties>
I then made sure I was filtering the appropriate html file (like described in Jason's solution), and then "extracted" the SVN_REVISION in the html file like so:
<script type="text/javascript">
...
var versionIdSuffix = '?v=${buildVersion}';
....
</script>
In a nutshell - I wasn't able to directly reference the {SVN_REVISION} property from inside the html file, so I "wrapped" it through <properties>, letting maven reference it instead.
Related
How do I create javadocs that link to files in the local filesystem in offline mode?
I am building javadocs for a java package and want the links of external packages (including java.lang) to point to a local copy. This works by setting the links property like so:
<configuration>
<links>
<link>/usr/share/doc/default-jdk-doc/api/</link>
</links>
</configuration>
However, the links property is ignored when working offline, even when
linking to a local copy of the javadocs. My understanding is that in such case, I should be using offlineLinks but I can't make it work.
All documentation I see for offlineLinks sets url to an external URL and location to a local file. The use case seems to be creating links to external server, by using a local copy. I have tried to set both url and location to the same value but this seems to be ignored.
<offlineLinks>
<offlineLink>
<url>/usr/share/doc/default-jdk-doc/api/</url>
<location>/usr/share/doc/default-jdk-doc/api/</location>
</offlineLink>
</offlineLinks>
I have created a minimal example as a github gist which I am calling like so:
mvn --offline javadoc:javadoc
It has a single package and method that takes a String as argument. I want the javadocs to create a link to a local copy of the docs but instead I keep getting String linked to docs.oracle.com instead.
The javadoc program would handle the -links option properly, even if it was a local directory and there was no without internet connection. The problem is the maven javadoc plugin which ignores the links property in offline mode. The solution is to pass that option directly to the javadoc program via the additionalparam property like so:
<configuration>
<additionalparam>-link /usr/share/doc/default-jdk-doc/api/</additionalparam>
</configuration>
This has two problems:
It becomes too long if linking to many different packages. In theory, one should be able to pass multiple -link options in a single additionalparam parameter.
The additionalparam is deprecated. However, there is no other maven property to pass javadoc options directly so hopefully they won't actually remove it.
The offlineLinks property, which would map to the command line option -linkoffline seems to really require an external URL. I am unsure if that's a requirement in the javadoc program or in the maven javadoc plugin.
I am working on getting the tool JNI4NET working so that I can use some Java code I have within my C# application. As a simple initial test I have created a simple Java class library with a single class Person with one method public String GetName() { return "NoBody"; }. From here I have been following along with the samples given in the JNI download to edit the generateProxies.cmd to create the DLL wrapper of the jar.
I didn't have much luck with this so I decided to try to perform the same action but with the sample, specifically the sample entitled myJavaDemoCalc. When executed generateProxies.cmd in the sample folder an error is thrown.
(I will transcribe this picture if need be)
I have followed the link in the exception though while I somewhat understand what it means I am not sure if it is necessarily safe to enable loading from remote sources as it suggests at the end of the linked article.
I am also confused why the exception is being thrown seeing that the generateProxies.cmd and thus ProxyGen.exe is being run from my C: drive.
Anyone have an idea of what I could try next or know the issue here?
For reference here is the generateProxies.cmd source from myJavaDemoCalc
#echo off
copy ..\..\lib\*.* work
..\..\bin\proxygen.exe work\myJavaDemoCalc.jar -wd work
cd work
call build.cmd
cd ..
echo compiling usage
csc.exe /nologo /warn:0 /reference:work\jni4net.n-0.8.8.0.dll /reference:work\myJavaDemoCalc.j4n.dll /out:work\demo.exe /target:exe MyCalcUsageInDotnet.cs
I assume you downloaded that zip file and then immediately Extracted all files.
However, because that zipfile did originate from an untrusted zone, being the internet, the files in it will also remain untrusted. It contains an alternate data stream with a zone identifier.
When those assemblies get loaded by the framework, it checks if they can be trusted. Assemblies with that zone identfier still present don't get loaded. That is the exception you get:
System.IO.FileLoadException: Could not load file or assembly 'file:///jni4net.n-0.8.8.0.dll' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515) --->
System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch.
The quickest solution to resolve this is to open the properties window of the downloaded zip file and tick unblock before you extract all files:
If you already extracted all the files to a folder you can use the powershell command unblock-file
Get-ChildItem -Path 'c:\path\to\files' -Recurse | Unblock-File
But if you're sure that you will always run proxygen.exe with trusted assemblies, you can add the suggestion offered in the MSDN article by adding the loadFromRemoteSources element in the existing proxygen.exe.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
<!-- trust all the thingz -->
<runtime>
<loadFromRemoteSources enabled="true"/>
</runtime>
</configuration>
I'm looking at an issue in a mature commercial product.
In a nutshell, we are using part of the Apache POI library to read in a Word .DOC or .DOCX file, and convert it into XSL-FO so that we can do token replacements. We then use FOP – embedded into the Java program - to convert the FO data into a PDF for printing. The catch is, all this is being done on the client inside a Java applet running inside Internet Explorer.
Originally we were using FOP 0.93, which worked reasonably well. However, it was not able to utilise the fonts inside the DOC file when generating the PDF and would map everything to Times, which one of the customers did not like. In theory it could be made to work by adding some kind of font metrics data, but that would require a relatively complex definition for every font it was likely to encounter and we can’t predict what the client is liable to use outside of the MS core fonts set.
To fix this, FOP was upgraded to 1.0, which added support for autodetecting the fonts from the operating system. This worked, but we noticed that the image processing had stopped working and the letterheads had disappeared.
What appears to have happened is that the image loader inside FOP was rewritten at some point between 0.93 and 0.95 so that instead of using Jimi and JAI it now uses ImageIO. The earlier implementation worked fine, but the new code doesn’t like being run as an applet.
Images are embedded in URIs in the FO data so we get an error like this:
2014-09-30 17:00:10,607 ERROR [org.apache.fop.apps.FOUserAgent] Image not available. URI:
data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAABSCAIAAABysmn6AAA...
...ggg==. Reason: org.apache.xmlgraphics.image.loader.ImageException: The file format is not supported. No ImagePreloader found for data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAABSCAIAAABysmn6AAAA...
When run through a test harness, the correct output is generated, but when run as an applet inside the browser we get the above error which makes me suspect that the browser applet security is jamming the ImageIO plugin loader somehow.
The guts of the FOP transformation, i.e. the bit which is triggering the error is this:
// Step 4: Setup JAXP using identity transformer
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(); // identity transformer
transformer.transform(src, res);
...which is all being run inside a PrivilegedAction block since in FOP 1.0 it needed file I/O access to manage the font cache.
Running the standalone FOP 0.93 and 1.0 programs under linux and using strace shows that it is writing out temporary files for the image data, but both 0.93 and 1.0 do similar things, so it shouldn’t be that by itself, especially since it should have permission to create temp files already.
I've tried different versions of the JRE since some builds a few years back apparently had security issues with the ImageIO library, but to no avail.
Any ideas?
Thanks,
In case anyone else has something similar, this turned out to be caused by the way the project was being built in Maven.
Fop 1.0 and above use the xml-graphics-commons library to facilitate the image rendering. As mentioned in the question, this uses a plugin registry which is configured using the following files inside the JAR:
META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImageConverter
META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactory
META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImagePreloader
...each of these contains a list of the image decoders which will be supported.
The problem is that xml-graphics-common ships these files with a sensible list of defaults, while FOP also has a conflicting set of defaults, which for some weird reason disable all of the image decoders, and that one was taking priority.
To solve the problem, I made sure that my maven pom.xml file imported xml-graphics-common before FOP, so that its defaults took precedence, and at that point everything sprang to life.
I am still not sure why the code was working correctly as a standalone test program, but I suspect it was the way the classpath was being handled being different to it running in plugin mode.
In my case the plugin registry loaded ImagePreloaders from both the plugin files and mixed them together. Yet the error still appeared. I was inserting an SVG file into a PDF file. The root cause was incorrect version of org.apache.xmlgraphics:batik-svg-dom. The 1.7 version was required by the org.apache.xmlgraphics:fop:1.1, however, the 1.8 version was on the classpath.
There is a key difference between the two versions: the org.apache.fop.image.loader.batik.PreloaderSVG class needs org.apache.batik.dom.svg.SAXSVGDocumentFactory from the version 1.7 on the classpath. If it gets org.apache.batik.anim.dom.SAXSVGDocumentFactory from the 1.8 version it does not work as expected.
This SO question: Where has org.apache.batik.dom.svg.SVGDOMImplementation gone? was helpful to me when resolving this issue.
Just been struggling with this one. If you're using the maven-shade-plugin to create an uber jar, use the ServicesResourceTransformer to merge all the services configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<!-- snip -->
<configuration>
<transformers>
<!-- snip -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
thanks for the post!
I can assert that this also works by changing ordering in Eclipse!
in my case, under Windows it was working fine, but same JAR file in RHEL raised an error
I have a checkstyle report as xml file and want to generate a html report which lists what kind of errors occurred how many times and in which files they occurred. Something like this example.
Is there a tool to do that?
If you are using mvn to do this, mvn checkstyle:checkstyle will generate an xml format report, or with the option -Dcheckstyle.output.format=plain just plain text. Both of these will only list the errors and won't give any summary.
The summary html file is found in the target directory, however I found the images and the CSS are missing so it looks pretty bad.
mvn site will generate the HTML format report like your image. However it will also generate large amounts of other reporting material and takes a long time.
I've also found another problem - mvn checkstyle:checkstyle will only find your config files if you include the file:// protocol in the checkstyle plugin config, e.g.
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.13</version>
<configuration>
<configLocation>file://${basedir}/checkstyle/checkstyle.xml</configLocation>
</configuration>
</plugin>
However mvn site only takes a directory, and can't handle the file://
I would like to append the output JAR filename of a Netbeans project with some version number: something like 1.0, 2.0b or even a Subversion revision number. I can't seem to find anything on this, though. I am also not sure if this would the responsibility of the build system (Ant) or if the IDE (Netbeans) can delegate the process. Is there a centralised, clean way of doing this?
IMO, this is the responsibility of the build system, not of the IDE. Let me say it in other way: don't rely on your IDE to build your project, use a build tool. Using an IDE is fine during development but being IDE dependent to build a project is not a good thing (what if you change your IDE tomorrow, what if you want to build your project on another machine/OS without that IDE, what if you want to build your project on a headless machine, what if you want to automate your build, what if someone wants to build that project and doesn't have that IDE, etc, etc). Really, this is what build systems are for.
Now, regarding your initial request, there are plenty ways to add a version number. One of them is to use the Ant's BuildNumber task:
This is a basic task that can be used to track build numbers.
It will first attempt to read a build number from a file (by default, build.number in the current directory), then set the property build.number to the value that was read in (or to 0, if no such value). It will then increment the number by one and write it back out to the file. (See the PropertyFile task if you need finer control over things such as the property name or the number format.)
Use it for example like this:
<target name="jar" depends="compile">
<property name="version.num" value="1.00"/>
<buildnumber file="build.num"/>
<jar destfile="foo-${version.num}-b${build.number}.jar"
basedir="."
includes="**/*.class"
/>
</target>
Or you could indeed add subversion revision number. An easy way to do this seems to install the SVNAnt task and use the status task:
<target name="revisionnumber">
<!-- get the svn revision number -->
<svn>
<status path="application.cfm" revisionProperty="svn.revision" />
</svn>
<echo>Sandbox Revision: ${svn.revision}</echo>
</target>
Finally, another option would be to use Maven instead of Ant which has a built-in version management feature as pointed out by cetnar.
I'm not sure if it's the best way, but we put it in MANIFEST.MF file like this:
Implementation-Version: 2.0b
We can get this value programmatically like this:
String version_num = this.getClass().getPackage().getImplementationVersion();
If you feel like using a tool to handle your builds then there are lots about, such as CruiseControl, which is ANT based and has pretty deep integration with your source code control.
I use it to automatically increment a build number and use that as the last digit in my version number for the jar, e.g. 1.4.168, where 168 is the build number. I am just about to get it to put a label into CVS just before the fetch with the build number so I know exactly what code is in the jar.
Well is done default by Maven. Even if you want name your jar file with more detailed information you can use build number plugin.
EDIT
At begining I misunderstood your question so following part relates to adding this information inside jar files.
You can do it yourself by creating manifest file. In Maven it you can tune proces of creating manifest file by additional configuration. I suppouse (I'm sure) that in Ant should be similar functionality.
you can use maven for vesion and read it from pom.
read this article:
Embedding the maven version number
at
http://happygiraffe.net/blog/2008/10/01/embedding-the-maven-version-number/