ui:param ... and caching

I have the following thing:

<ui:param name="randomVideo" value="#{bean.randomVideo}" />
<a href="#{randomVideo.link}">#{randomVideo.text}</a>

Because <ui:param> does not cache the variable, Bean.getRandomVideo() is called twice, and the worst part is that the .text and .link are from different videos. I have already tried <c:set and <f:param. They both do not set the variable, maybe because I'm with facelets (JSF2).

Any ideas?

JSF 2 does not update the url after a form action?

I did not know that http://www.mkyong.com/jsf2/jsf-page-forward-vs-page-redirect/

I did not know that the upper link solves that http://www.mkyong.com/spring-mvc/handling-duplicate-form-submission-in-spring-mvc/ (which is a problem I have in my current project).

 

 

 

 

 

 

 

 

 

 

 

 

 

I hate getters and setters

I hate getters and setters in java. Half of my code is filled with them. They are pointless boilerplate code that says nearly nothing. 99.9% (I made that number up, but it sounds reasonable) percent of the cases they don't have any additional code in them.

And it is really hard to see whether a variable is read-only/read-write/write-only. You have to find the getters/setters to see that.

I have a notation where I put all the modifiers at the end of the class and separate them with a page of whitespace.

I don't like the C# solution - it's not really shorter, only binds the getter and setter together.

I have a proposition: use annotations:

    @Getter @Setter
    private boolean subscribedForEmailNotification;

And one wants to write extra code, one should be able to use the old notation. The compiler will check for collisions.

I don't see any reason why this cannot become the next syntactic sugar in java where one saves a bunch of useless code-writing.

RichFaces presentation

This is a lecture I presented that is part of the JavaEE course.

The presentation was prepared by Radoslav Ivanov.

Exercises: RichFacesJSF1.2 project for eclipse
Installation: eclipse -> import -> existing project into workspace -> archive -> finish

Richfaces installation instructions for Eclipse in the presentation (ppt).


Disable session persistence in Tomcat

This a pretty common issue when running java web applications on Tomcat. One puts an object into session and after a restart one gets:

Caused by: java.io.NotSerializableException: java.lang.Object

It may not always be java.lang.Object, any class not implementing java.io.Serializable could be in this error.

This is due to Tomcat's default behavior of serializing all the sessions and after restart trying to deserialize them. (A good question is how does tomcat serialize them in the first place, but no time to research that).

The solution is pretty simple, find tomcat_dir/conf/context.xml and find a place where it says:

<!-- Uncomment this to disable session persistence across Tomcat restarts -->

This works for both Tomcat 6 and Tomcat 7. Tomcat guys did the effort to prepare everything so it's easy for us.

This solution deserves a blog post because every once in a while I get bugged by this problem and have forgotten the solution. Now I know where to search for one.

Why is java development so windows oriented?!

I'm using a macbook. Obviously I'm using Mac OS. Not so obviously actually - recently I saw a few people using Windows 7 on a macbook.

JDK. Developing java applications on a Mac OS is not so straightforward as it is on windows. When you start on Windows, the first thing you do is download the JDK - that's easy. On Mac OS you don't have a real JDK, you have Java for Mac OS X. It's not the same. It's always late. Using SoyLatte they made a darwin port called openjdk6 that is a lot more like a real JDK. With JavaSE 7 it's even worse - there are binaries for Windows, on Mac OS one has to build it manually which is not that easy.

Eclipse. Then there's Eclipse. Thank god - there's an Eclipse.dmg that is pretty easy to install. But (there's always a but), the shortcuts are a bit changed. Alt+Shift+X becomes ⌘+⌥+X. There's also the speed issue - Eclipse is not as fast on Mac OS as it seems on a Windows machine.

Browsers. One major setback is that if one does front-end, one needs Internet Explorer to test. Otherwise QAs come and kick one's ass because something doesn't work on IE6 for example. I hate Internet Explorer. Not only IE6, all of them.

Configuration. In my project I have:

File file = new File(element.replace("file:", ""));

my Windows-using colleagues have

File file = new File(element.replace("file:/", ""));

The good thing is that since Mac OS is unix-based I have the settings that are closer to the Ubuntu we deploy our production on.

I don't know - maybe I should buy a new Macbook with a fast SSD with a lot more juice into it than the one I have now (a two-year-old one that hasn't been reinstalled since). Now there's the question - should I buy the 13" or the 15"?

P.S. The things are getting a lot better. OpenJDK6 port is pretty mature (I use it), OpenJDK7 port is coming soon. Apple donated it's JavaSE port to Oracle, so soon Java's download page would feature a .dmg file, which will be awesome.

Still I think developing java apps on a macbook is a bit harder than on a Windows machine. I wouldn't go back to Windows because of the awesome hardware and because the OS is so much better for anything else.

How to make Eclipse validate XSL (and of course XML) files

Intro on Eclipse

Eclipse has two major bundles:

  • Eclipse IDE for Java Developers
  • Eclipse IDE for Java EE Developers.

Info here: http://www.eclipse.org/downloads/

The major difference is that Eclipse for JavaEE includes the Web Tools Platform (WTP). WTP has editors, designers, JavaEE perspective, new projects and so on.

I generally prefer to use the ‘Java’ perspective as opposed to the ‘JavaEE’ perspective, because the latter is too cluttered, but the one thing from WTP without which I cannot live is the XML editor. There are variations for XSL transformations and XML Schemas.

XML Schemas (XSD)

By default Eclipse can validate XML Schemas, because it has the schema for XSDs. Did you get this one? Let’s try again. XSD is a language written in xml that defines rules for xml files who want to conform to certain rules. This allows us to validate such files versus a schema. Finally XSD is also XML, so there is a special XSD Schema that defines how to write XSD Schemas. And the dog catches its tail.

XML Schema language is also defined in DTD. DTD is the predecessor of XSD.

Anyway, if you want to learn more, go to W3C Schools - the best place to learn XML, XSD, XSLT. This is also the official site of WWW Consortium (W3C) which handles the expert groups that define these standards.

Where is XSL.xsd?

XSL is written in xml, so there is an XSD Schema that defines how to write XSL files.

The schema for XSLT 2.0 (2007 revision) is here: http://www.w3.org/2007/schema-for-xslt20.xsd (the most up-to-date)
The DTD for XSLT 1.0 (1999 revision) is here: http://www.w3.org/TR/1999/REC-xslt-19991116.xml (I couldn’t find XSD for XSL 1.0, maybe because XSL 1.0 is too old)

So the only thing I need to do is put XSL.xsd in Eclipse?

Yes. Here’s how: go to Window –> Preferences and then to XML –> XML Catalogs:

(XML Catalogs are a very interesting topic. There’s an article on them in this blog here)

Eclipse 3.5 preferences

Then "Add”:

Add XML Catalog from http

There are 3 ways to add an XML Schema to Eclipse

  1. Via an URL (as in the picture)
  2. Via a workspace location
  3. Via a file on the file system

How do we validate?

Here’s how:

Validate button in Eclipse

Via the "Validate" button on the context menu on any XML/XSL file.

The exact same thing can be performed for any XML File that has to be validated against an XML Schema (or DTD, of course)

Certificates, keystores, java keytool utility and openssl

(Updated: four six typos fixed)

I)
From time to time I need a self-signed certificate. I use the java keytool utility to make one:

For a JKS (Java Key Store format):

keytool
-genkeypair
-keystore mihail.stoynov.jks
-storepass mihail.stoynov
-alias mihail.stoynov
-keypass mihail.stoynov
-keysize 2048
-keyalg RSA
-sigalg sha1withrsa
-dname "cn=Mihail Stoynov,
ou=MyCompany Bulgaria, o=MyCompany, L=Sofia, S=Sofia, c=BG"
-validity 3650
-v

For a PKCS#12 keystore:

keytool
-genkeypair
-keystore mihail.stoynov.p12

-storetype pkcs12
-storepass mihail.stoynov
-alias mihail.stoynov
-keypass mihail.stoynov
-keysize 2048
-keyalg RSA
-sigalg sha1withrsa
-dname "cn=Mihail Stoynov, ou=MyCompany Bulgaria, o=MyCompany, L=Sofia, S=Sofia, c=BG"
-validity 3650
-v

When the public certificate is needed separately, one can be exported in a file (mihail.stoynov.cer) like this:
(from a JKS)

keytool
-exportcert
-keystore mihail.stoynov.jks
-storepass mihail.stoynov
-alias mihail.stoynov
-keypass mihail.stoynov
-file mihail.stoynov.cer
-v

 

(from a PKCS#12)

keytool
-exportcert
-keystore mihail.stoynov.p12

-storetype pkcs12
-storepass mihail.stoynov
-alias mihail.stoynov
-keypass mihail.stoynov
-file mihail.stoynov.cer
-v

 

NOTE: keep storepass and keypass the same for easy importing into browsers

II)
Sometimes self-signed certificates are not enough and a CA root certificate must be made in order to sign a group of certificates.

First a Certificate signing request (CSR) must be made:
(from a JKS)

keytool
-certreq
-keystore mihail.stoynov.jks
-storepass mihail.stoynov
-alias mihail.stoynov
-keypass mihail.stoynov
-v
>> mihail.stoynov.csr

(from a PKCS#12)

keytool
-certreq
-keystore mihail.stoynov.p12

-storetype pkcs12
-storepass mihail.stoynov
-alias mihail.stoynov
-keypass mihail.stoynov
-v
>> mihail.stoynov.csr

(the output is directed to a file: mihail.stoynov.cer)

The file looks something like that:

-----BEGIN NEW CERTIFICATE REQUEST-----
MIICtTCCAZ0CAQAwcDELMAkGA1UEBhMCQkcxDjAMBgNVBAgTBVNvZmlhMQ4wDAYDVQQHEwVTb2Zp
YTEQMA4GA1UEChMHTWF0ZXJuYTEWMBQGA1UECxMNTWF0ZXJuYSBTb2ZpYTEXMBUGA1UEAxMOTWlo
YWlsIFN0b3lub3YwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ7XpdyHuF9ApZodSn
GS9/TiUtXqryPDD0elzlP2QreSkfYv8IaXnB1Xy1ZVmda/d+P4TZ/aHvAhDwQPcei4KaoRzJWX9I
Yz9hi4cmKksjg8ufDZzXUuMwtbVlricc5vWg1HcSsQJ8vpLCBIelliDJOxc4skDcT23LGQttiv0b
23pjMthEe2tJVp37Tnwr29SLz0AGziVwzb5cfAXU4PzpiASr8vF2A0c2DObS7zM5Wp7jXWIe71P5
BZgIMcUUGlCdfLQRoA7URWN2Yx2qH8gyiNaIaZYZB6o2ib8rH3UmDl/ErKJgWQyS7sr4bANY9WpA
m7H2nXfGs+X88xSbA0JRAgMBAAGgADANBgkqhkiG9w0BAQUFAAOCAQEAIn81dCSpVbI7IDLO2L2p
MW1gnjvuRs9xm6M9rMV6Kwy0Nw05qL0H8tTsFaq4J7bLBXJeXmiREUbrtpbHxLUfjtaqs5q5Txxn
c7Cm5kj7t9PWeRTW0rbzRssgT+sHqUlMKMydB8E+gGEIMQdgwdurhjpD7aevOOeN5fvv9kV7Rszv
6nC8dixyrsiiWjLUGJRP7I9HrEAXKfk3JluSYKS/ZNhTIw5a7fKvhXbRPlN1lDSvdkJAtcaG/9dZ
3KlXL7ozL8sOQTjFxUhN6kS6QujJ1T7TlkWHu9/ivIAkuXBu8P/czyLyjf1JD9fnwGnxCO2FPmcX
9/2IpwG33mMpaAmXpA==
-----END NEW CERTIFICATE REQUEST-----

Did we forget something? Yes, there's no Root CA certificate. Let's make one:
(JKS)

keytool
-genkeypair
-keystore mycompany.root.ca.jks
-storepass "mycompany.root.ca"
-alias "mycompany.root.ca"
-keypass "mycompany.root.ca"
-keyalg RSA
-keysize 2048
-sigalg SHA1withRSA
-dname "cn=MyCompany Bulgaria, ou=Office No 5, o=MyCompany, L=Sofia, S=Sofia, c=BG"
-validity 3650
-v


(PKCS#12)

 

keytool
-genkeypair
-keystore mycompany.root.ca.p12

-storetype pkcs12
-storepass "mycompany.root.ca"
-alias "mycompany.root.ca"
-keypass "mycompany.root.ca"
-keyalg RSA
-keysize 2048
-sigalg SHA1withRSA
-dname "cn=MyCompany Bulgaria, ou=Office No 5, o=MyCompany, L=Sofia, S=Sofia, c=BG"
-validity 3650
-v

Problem No 1
Keytool cannot sign CSRs. Period.

Now what do we do?

I went to OpenSSL.

In order to sign with OpenSSL I needed the root certificate in the PEM format.
P12 (PKCS#12) -> PEM:

openssl
pkcs12
-in mycompany.root.ca.p12
-out mycompany.root.ca.pem

Sign the CSR with OpenSSL:

openssl
x509
-req
-in mihail.stoynov.csr
-CA mycompany.root.ca.pem
-out mihail.stoynov.signed.cer
-days 3650
-CAcreateserial

(I don't know what -CAcreateserial is but it works)

So now I have mihail.stoynov.signed.cer.

The last step is to import it to mihail.stoynov.p12 (or .jks) in order to override the self-signed certificate with the one signed by the MyCompany Root CA.

A Prerequisite step to that is to import mycompany.root.ca.cer into mihail.stoynov.p12 (or .jks) because every certificate in the chain must be contained in the certificate chain of mihail.stoynov.

Problem No 2
Importing mycompany.root.ca.cer into mihail.stoynov.p12 fails but importing it into mihail.stoynov.jks works?!

JKS:

keytool
-importcert
-keystore mihail.stoynov.jks
-storepass mihail.stoynov
-alias mycompany.root.ca
-keypass
mycompany.root.ca
-file mycompany.root.ca.cer
-v

(this one works)

PKCS#12

keytool
-importcert
-keystore mihail.stoynov.p12

-storetype pkcs12
-storepass mihail.stoynov
-alias mycompany.root.ca
-keypass
mycompany.root.ca

-file mycompany.root.ca.cer
-v

this one fails with:

Owner: CN=MyCompany Bulgaria, OU=Office No 5, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Issuer: CN=MyCompany Bulgaria, OU=Office No 5, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Serial number: 49b8c365
Valid from: Thu Mar 12 08:12:13 GMT+00:02 2009 until: Sun Mar 10 08:12:13 GMT+00:02 2019
Certificate fingerprints:
MD5:  1C:0C:82:0D:35:C8:1E:48:74:9F:13:43:C9:AE:D0:F7
SHA1: DB:BB:D7:DB:8C:33:AA:06:6D:CF:D2:5C:EB:64:01:D5:AD:AB:94:38
Signature algorithm name: SHA1withRSA
Version: 3
Trust this certificate? [no]:  y 

keytool error: java.security.KeyStoreException: TrustedCertEntry not supported
java.security.KeyStoreException: TrustedCertEntry not supported
at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineSetCertificateEntry(PKCS12KeyStore.java:620)
at java.security.KeyStore.setCertificateEntry(KeyStore.java:941)
at sun.security.tools.KeyTool.addTrustedCert(KeyTool.java:1958)
at sun.security.tools.KeyTool.doCommands(KeyTool.java:818)
at sun.security.tools.KeyTool.run(KeyTool.java:172)
at sun.security.tools.KeyTool.main(KeyTool.java:166)

Actually P12 format does not permit trusted certificates. It is inteded to contain key/pairs only. So importing mycompany.root.ca.cer into mihail.stoynov.p12 failed.

I tried several things:

1) Importing mihail.stoynov.signed.cer directly into mihail.stoynov.p12:

keytool
-importcert
-keystore mihail.stoynov.p12
-storetype pkcs12

-storepass mihail.stoynov
-alias mihail.stoynov
-keypass mihail.stoynov
-file mihail.stoynov.signed.cer
-v

and the response was:

keytool error: java.lang.Exception: Failed to establish chain from reply
java.lang.Exception: Failed to establish chain from reply
at sun.security.tools.KeyTool.establishCertChain(KeyTool.java:2662)
at sun.security.tools.KeyTool.installReply(KeyTool.java:1870)
at sun.security.tools.KeyTool.doCommands(KeyTool.java:807)
at sun.security.tools.KeyTool.run(KeyTool.java:172)
at sun.security.tools.KeyTool.main(KeyTool.java:166)

2) Importing mycompany.root.ca.cer into cacerts:

keytool -importcert -trustcacerts -file mycompany.root.ca.cer

This again didn't fix the problem.

Solution to Problem No 2:
Transform P12 to JKS, import the root certificate and the signed certificate into JKS keystore, transform the modified JKS back to P12.

1) Transform P12 to JKS

keytool
-importkeystore
-srckeystore mihail.stoynov.p12
-destkeystore mihail.stoynov.jks
-srcstoretype pkcs12
-srcstorepass mihail.stoynov
-deststorepass mihail.stoynov

2) import the root certificate into the JKS keystore

keytool
-importcert
-keystore mihail.stoynov.jks
-storepass mihail.stoynov
-alias mycompany.root.ca

-keypass
mycompany.root.ca

-file mycompany.root.ca.cer
-v

3) import signed certificate into JKS keystore

keytool
-importcert
-keystore mihail.stoynov.jks
-storepass mihail.stoynov
-alias mihail.stoynov
-keypass mihail.stoynov
-file mihail.stoynov.signed.cer
-v

4) transform the modified JKS back to P12

keytool
-importkeystore
-srckeystore mihail.stoynov.jks
-destkeystore mihail.stoynov.p12
-deststoretype pkcs12
-srcstorepass mihail.stoynov
-deststorepass mihail.stoynov

it said something like:

Entry for alias mihail.stoynov successfully imported.
Problem importing entry for alias mycompany.root.ca: java.security.KeyStoreException: TrustedCertEntry not supported.
Entry for alias mycompany.root.ca not imported.
Do you want to quit the import process? [no]:  n
Import command completed:  1 entries successfully imported, 1 entries failed or cancelled

I clicked yes, and it worked.

Now let's see what's the difference between mihail.stoynov.jks and mihail.stoynov.p12:
JKS:

$ keytool -list -keystore mihail.stoynov.jks -storetype jks -storepass mihail.stoynov -v

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

Alias name: mihail.stoynov
Creation date: Mar 12, 2009
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=Mihail Stoynov, OU=MyCompany Sofia, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Issuer: CN=MyCompany Bulgaria, OU=Office No 5, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Serial number: f0e465bb77420e30
Valid from: Thu Mar 12 09:29:19 GMT+00:02 2009 until: Sun Mar 10 09:29:19 GMT+00:02 2019
Certificate fingerprints:
MD5:  40:9D:C2:DE:AE:11:1E:01:92:F9:C8:01:C5:92:69:CB
SHA1: D2:D0:03:5C:50:BC:F8:6C:EB:C0:36:B6:B0:8D:A8:3B:9E:B6:7B:B4
Signature algorithm name: SHA1withRSA
Version: 1
Certificate[2]:
Owner: CN=MyCompany Bulgaria, OU=Office No 5, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Issuer: CN=MyCompany Bulgaria, OU=Office No 5, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Serial number: 49b8c365
Valid from: Thu Mar 12 08:12:13 GMT+00:02 2009 until: Sun Mar 10 08:12:13 GMT+00:02 2019
Certificate fingerprints:
MD5:  1C:0C:82:0D:35:C8:1E:48:74:9F:13:43:C9:AE:D0:F7
SHA1: DB:BB:D7:DB:8C:33:AA:06:6D:CF:D2:5C:EB:64:01:D5:AD:AB:94:38
Signature algorithm name: SHA1withRSA
Version: 3

*******************************************
*******************************************

Alias name: mycompany.root.ca
Creation date: Mar 12, 2009
Entry type: trustedCertEntry

Owner: CN=MyCompany Bulgaria, OU=Office No 5, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Issuer: CN=MyCompany Bulgaria, OU=Office No 5, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Serial number: 49b8c365
Valid from: Thu Mar 12 08:12:13 GMT+00:02 2009 until: Sun Mar 10 08:12:13 GMT+00:02 2019
Certificate fingerprints:
MD5:  1C:0C:82:0D:35:C8:1E:48:74:9F:13:43:C9:AE:D0:F7
SHA1: DB:BB:D7:DB:8C:33:AA:06:6D:CF:D2:5C:EB:64:01:D5:AD:AB:94:38
Signature algorithm name: SHA1withRSA
Version: 3

*******************************************
*******************************************

 

P12 (PKCS#12)

$ keytool -list -keystore mihail.stoynov.p12 -storetype pkcs12 -storepass mihail.stoynov -v

Keystore type: PKCS12
Keystore provider: SunJSSE

Your keystore contains 1 entry

Alias name: mihail.stoynov
Creation date: Mar 12, 2009
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=Mihail Stoynov, OU=MyCompany Sofia, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Issuer: CN=MyCompany Bulgaria, OU=Office No 5, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Serial number: f0e465bb77420e30
Valid from: Thu Mar 12 09:29:19 GMT+00:02 2009 until: Sun Mar 10 09:29:19 GMT+00:02 2019
Certificate fingerprints:
MD5:  40:9D:C2:DE:AE:11:1E:01:92:F9:C8:01:C5:92:69:CB
SHA1: D2:D0:03:5C:50:BC:F8:6C:EB:C0:36:B6:B0:8D:A8:3B:9E:B6:7B:B4
Signature algorithm name: SHA1withRSA
Version: 1
Certificate[2]:
Owner: CN=MyCompany Bulgaria, OU=Office No 5, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Issuer: CN=MyCompany Bulgaria, OU=Office No 5, O=MyCompany, L=Sofia, ST=Sofia, C=BG
Serial number: 49b8c365
Valid from: Thu Mar 12 08:12:13 GMT+00:02 2009 until: Sun Mar 10 08:12:13 GMT+00:02 2019
Certificate fingerprints:
MD5:  1C:0C:82:0D:35:C8:1E:48:74:9F:13:43:C9:AE:D0:F7
SHA1: DB:BB:D7:DB:8C:33:AA:06:6D:CF:D2:5C:EB:64:01:D5:AD:AB:94:38
Signature algorithm name: SHA1withRSA
Version: 3

*******************************************
*******************************************

 

Do you see the difference?
It's in italic - JKS format keeps an extra trusted certificate of MyCompany Root CA.

Anyway both mihail.stoynov.jks and mihail.stoynov.p12 work perfectly.

P.S.
Does someone know better solutions to Problem No 1 and Problem No 2?
Does someone know how to sign certificates but without the cumbersome CSR step?

@Override in eclipse

When one implements an interface, the template in Eclipse puts an @Override and it does not complain about it. Ant javac task also compiles without warnings.

Sometimes other Eclipse instances start to complain exactly for that @Override stating that there's no method that's overridden. Well, Eclipse, please do make up your mind.

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Override.html
"Indicates that a method declaration is intended to override a
method declaration in a superclass. If a method is annotated with
this annotation type but does not override a superclass method,
compilers are required to generate an error message."

Well, that's not very clear. As far as I remember an Interface is a pure abstract class, right? So, which one's correct.

P.S. Sometime ago I was having a similar problem with Eclipse and generics - Eclipse only gave a warning about something (can't remember what exactly), but the javac said that it was an error - Google said something like "eclipse uses jikes, you use javac". So what, aren't there specs?!

Update: apparently JDK5 (or 1.5, suit yourself) does not allow that. So in order to get all the wrong @Overrides - set the Compliance level to 5.0 (Eclipse -> Window -> Preferences -> Java -> Compiler -> Compiler compliance level ) - and..... correct them. I have 29 left.

ant junitreport task cannot set vm arguments

ant junitreport task creates a html report from junit xml report files.
If the xml files are numerous enough and/or large enough (mine were 102MB total ), the task crashes with OutOfMemoryError.

Solution? set the GLOBAL variable ANT_OPTS. This changes defautl ant conf for the whole machine this setting is on.

Not very nice 🙂