Html4JavaUXStudy2014

In order to understand how good your API is (or at least how it satisfies time to market requirements), it is the best to perform a usability study. I ordered one for the Html4Java API in February 2014. Here are the observations.

The usability study was run by http://www.apiusabilitytesting.com/ and I can only recommend their service: I didn't have to bother with searching for participants, getting them in place, collecting results, etc. All of this was very simplified thanks to Denis @apiusabilitytst.

Very nice thing was the ability to do re-study - once the study was over, I improved the javadoc and ansked Denis' guys to look whether the HTML4Java API is any better. It was, but there were still few glitches - I fixed them in version 0.8.

Contents

Tasks

I had to think-up some tasks for the participants. Here is what I made up:

  1. Creating own application in Java that renders through HTML.
  2. Animating an HTML page from Java via knockout bindings:
  3. Communicating with a server using JSON & REST or WebSockets
  4. Create a Java API wrapper for some JavaScript library - provide an ability to call some library's functions from Java
  5. Interact with JavaScript from Java

all of these tasks were actually listed and documented in the javadoc, so my expectation was, it can't be that hard to follow them. But, we have usability studies to get surprised!

Creating own application in Java that renders through HTML

Comments related to the first task:

Eclipse is Broken

Getting the example working was easy. But there were compiling problems on Eclipse: the Data class was missing and it took me a while to understand what was going on. One option to make the setup easier is to change the pom.xml generated by the archetype to include the “target/generated-sources/annotations/” as a source folder, and put a note in the documentation that you should run “mvn compile process-classes” every time there’s a change in your model.

Done: Document the API behavior in Eclipse as it does not seem to deal with Maven appropriately.

You have to be very careful when you put names in strings, the compiler won’t complain until you run, and even then the error message could not be so clear (I did misspelled a property name, and it took me 15 minutes to see my mistake).

Done: Eclipse, probably does not deal well with annotation processors. Well, other IDEs do... For example participants using InteliJ Idea 13 finished the first task quickly without any complains.

Not a JavaEE Technology!

I then spend some time figuring out what was going on with the example, read the suggested docs, and trying some changes. I didn’t know Knockout.js, so I had to learn the basics. Using the Main class to start a BrowserBuilder was a bit weird, I would prefer a more common approach: building a WAR, running it on Tomcat or Jetty and using Chrome to inspect the html and js.

Done: Described various packaging options.

Why Model Annotation at All?

Why should we use annotations for the property Models? It seems easier to have a single @Model, and the properties are real attributes in the class. The main issue here is: what am I gaining in using the @Model with the properties instead of a simple bean? Using a bean would make the code easier to understand and to work with.

Valid: Yes, JavaBeans are well understood concept, and Java developers are used to them. Having a way to expose existing JavaBeans and use it from Knockout, would simplify migration. On the other hand, it requires reflection and the whole @Model API tried to avoid reflection. But yeah, there should be an optional module to convert a JavaBean to a model class and use it. Thanks.

Understanding Knockout.js

It isn’t clear from the documentation that a developer must be familiar with Knockout.js. “This API allows you to write your application logic in Java and present it using modern HTML rendering technologies like Knockout and” so I thought your API uses some similar technology like Knockout, but not Knockout itself.

Done: Point out that the Knockout website is great source of information for the HTML part of the technology.

Another observation is: I have no idea how the name scope would work when I have more than one model in the same page, or how to build a list, but this can be me not knowing Knockout.js, but I’m a bit unsure about how it would work from the sample code.

The compiler throws error but does not describe the problem. It seems to be a runtime exception. However the problem which I got after going deep into the stacktrace is that:

netscape.javascript.JSException: Error: Unable to parse bindings.
Message: ReferenceError: Can't find variable: on;

Note: Yeah, this is an exception coming from Knockout and it is a runtime exception. Currently there is no verification of the correspondence between the model and the actual tags in the HTML page.

Understanding Maven

Also, when I tried to download a project with Maven, I just copied your example command line “mvn archetype:generate -DarchetypeGroupId=org.apidesign.html - DarchetypeArtifactId=knockout4j-archetype -DarchetypeVersion=x.y” and it didn’t work, because of “-DarchetypeVersion=x.y”. Fortunately, I managed to try 7.5.0 instead of x.y and it worked.

Done: Should always replace the x.y with appropriate version in the documentation.

When I started to execute maven script from “Getting Started” the compilation was showing some errors with JDK 1.6, so I switched to 1.7.

Done: The desktop version requires JDK7 and JavaFX. Documented.

Animating an HTML page from Java via knockout bindings

Please really consider improving the documentation. I simple can’t get the “flow” and understand how to use the API. I am just using the existent examples, guessing and playing with them.

I based this task on the Task1. It took about 30 minutes to understand some details of Knockout.js (I hadn’t had experience with Knockout.js).

Note added: Probably talk more about knockout.js and warn that this is not JavaEE


It is strange for me that a getter for generated boolean property has prefix “is”, but the setter has prefix “set”. When I played with the example, I tried several times with “getOn()” and got compilation error, but finally managed that I should use “isOn()”.

Note: Follows JavaBean specification. Could be made configurable in the annotation however.

The creation of a simple BoxModel with X and Y values was easy, but I’ve had to recompile and process-classes a few times because I changed the properties names a few times. The problem I found is that I had already used the methods of the generated Box on the Main class, and maven would fail to compile the code (for example: I changed the property from x to xPosition, but I didn’t change the setX() on the Main class):

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-
plugin:2.3.2:compile (default-compile) on project task1: Compilation failure
[ERROR]
/Volumes/Oliphaunt/Users/user1/Documents/tasks/eclipse/task2/src/main/java/com/user1/
Main.java:[23,8] error: cannot find symbol

This was also annoying when I created a @ComputedProperty and I always forgot to change it’s parameters when I changed the @Model. Then I used the data-bind style to animate a green box based on the X,Y form inputs.

My issues interacting with the framework were the same as on Task1, and most of then would be gone if the Model were closer to a java bean.

Note: The optional module converting to JavaBean would be handy. At least users of Eclipse would have something that naturally works on their IDE...

Communicating with a server using JSON & REST or WebSockets

Online example really helped me. Not related to the task: it isn’t clear how to get access to nested JSON, for example:

{
  "html_url": "https://gist.github.com/6711031",
  "files": {
    "gistfile1.cs": {
      "filename": "gistfile1.cs",
      "type": "text/plain",
      "language": "C#",
      "raw_url": "https://gist.github.com/ENoteSync/6711031/raw/61f3637f472e1c625ec4075a93df5f56210459a0/gistfile1.cs",
      "size": 139
    }
  }
]

How to access “filename” property for example? I can’t find the answer in the documentation or examples.

Valid: Yes, this is not possible right now. Gists use JSON in a bit unexpected way (from my original point of view).

The problem with json/rest is that it’s not clear how it will handle complex rest/json models. Looks like we will need to define everything. It’s not clear from documentation, and I need to experiment, guess, and so on.

Done: It is enough to name just few fields, the rest will be ignored. Will fix the documentation.

Can we initialize our class object with local JSON file? If yes, maybe you should mention that in the docs.

Valid: Yes, if the URL is relative to the index.html page, it should be possible to load a .json file next to the page. Need to verify and document.

Does the API support other providers like XML or Database to initialize a class object?

Too complex: Possibly, but it requires own implementation of transfer: http://bits.netbeans.org/html+java/0.7.5/org/apidesign/html/json/spi/Transfer.html - this is way beyond the scope of initial tutorial.

The json I wanted to show: http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d?categoryId=77&format=json The categoryID would be the variable, but I started with a fixed category. Both examples I found was for an array of the same type, but the JSON I had is a type with properties and arrays inside it. I tried many combinations with the mappings, but I couldn’t make it work.

Invalid: The documentation for OnReceive annotation already contains non-array example!

Too cryptic error message:

java.lang.Exception: [object XMLHttpRequestProgressEvent]
at org.netbeans.html.ko4j.LoadJSON.notifyError(LoadJSON.java:187)

Finally it worked as I had included an extra parameter in the @Model

/** Generates class Resp which is a Java representation
* of appropriate JSON object sent from the server.
*/
@Model(className="Resp", properties={
@Property(name="url", type=String.class), this was wrong
@Property(name="one", type=String.class),
@Property(name="key", type=String.class)
})
static class RespImpl {

Action: Investigate, improve error messages.

Create a Java API wrapper for some JavaScript library

It’s not clear if I may pass parameters from javascript to java callback. Wondering if java may receive callbacks, which format it will accept. Created few functions like the one that changes background of document and other that prompts. Looks like we will need to store answers or states in model. Not clear if we may pass for example results of javascript execution right into model.

XXX: TBD.


It isn’t clear how to include native JS library to the project. Should I add <script src="http://ejohn.org/files/pretty.js" type="text/javascript"></script> or I should duplicate library implementation in “body”? I tried with <script> section and it didn’t work. Well, finally, after several attempts I found out correct place for JS library based on compilation errors (“com/mycompany/mavenproject1/DataModel.java:[34,8] error: Cannot find com/mycompany/mavenproject1/pretty.js in com/mycompany/mavenproject1/pretty.js”).

Document: Fixed the example, but possibly enlarge it.

From eclipse it is giving a

java.lang.UnsatisfiedLinkError:
test.Task4Model$TaskJS.chkAge(Ljava/lang/String;)I
at test.Task4Model$TaskJS.chkAge(Native Method)

Action: Investigate the sample.

Error message:
java.lang.NullPointerException
at org.apidesign.html.boot.spi.Fn$1.invoke(Fn.java:152)
at com.atelles.Mul.multiply(Mul.java)
at com.atelles.BoxModel.showBoxPosition(BoxModel.java:34)

Fixed: http://hg.netbeans.org/html4j/rev/e43da8fe7dbc

Interact with JavaScript from Java

Incidentally if executing the same file from eclipse is producing an error of

java.lang.UnsatisfiedLinkError:
test.Task5Model.usefulModify([Ljava/lang/String;)[Ljava/lang/Object;
at test.Task5Model.usefulModify(Native Method)
at test.Task5Model.chkage(Task5Model.java:28)

Done: The file really needs to be postprocessed by one of the Maven tasks.


The question related to the tasks 4 and 5 – can we accept a custom class as an input while making call from js to java or vice versa (I see a real need of that in one of my projects)?

Yes: It should be possible to pass any Java object to JavaScript and any JavaScript object to Java and later use them in calls or callbacks.

Questions

Did you have to leave the editor and read the documentation, why?

Yes I had to. The NetBeans editor did not have the documentation for the API attached by default plus I hadn’t used Knockout.js before, so I read Knockout docs too.

Yes, I think 70% of the time I read the API documentation, Knockout.js documentation and tried to fix some compiler errors. As I said in the notes for the tasks, there is a lack of clear and consistent documentation. When I started working with the API, I knew almost nothing about Knockout.js, but thanks for their great tutorials I got the basics very fast, literally 20-30 minutes. But, unfortunately, I couldn’t say the same about the API documentation.

In order to understand API I read documentation, checked examples, because I need to have a picture in my head what it is all about. Some classes like Model have reference to example, but would be cool if you also add examples which show role of other classes and their usage, because x+2y+5Z = 322 example doesn’t make sense if we don’t know value of each, right? So once I read documentation, checked examples I was referring to examples and quickly adjusted that by my needs and ramped-up into it. So I didn’t leave my editor often, because it’s no so complex to be able to keep the picture in my head.

Also different parts of documentation show different aspects of behavior, but complete picture needs description probably of each class and their combination between them. I would really create some tutorials and more samples. So people start from the case which is very close to their need and adjust it a bit to their need, check some documentation, but not fully load that into their heads.

Did anything unexpected showed up during working with the API? Was the feedback from the library or the tooling helpful in case of problems?

Yes. During the Task 4, I was not able to use an external javascript library using @net.java.html.js.JavaScriptResource annotation. Although there were no compiler errors there was a nullpointer exception. The stack trace wasn’t helpful at all due to the class generation.

Actually I didn’t experience some crashes or unexpected failures. Everything works pretty smooth. On a separate note - NetBeans IDE 8 works very good with the library. Intellisense works just great for the API. It really helps, especially when a developer is not familiar with the API.


Well, java browser which is started by maven was crashing during REST calls. Not sure why. Probably due to bad model matching.

Yes. In Task1 I had created a simple html form with four input texts and a Submit button, I was not able to bind it to the code. Documentation was not sufficient in covering all types of bindings, and I had to resort to searching examples to get a hint on what to do. Also in some cases like @OnReceive and @JavaScriptResource the trace is difficult to debug.

Was it easy to do debugging & testing? If not, what was the obstacle?

Fortunately, I managed to run the project in NetBeans IDE 8, so debugging and testing were very easy. Well, I am fantasizing now, but as soon as html file and model file are tied together logically, so it would be great if a developer has an ability to see the two files on the same screen simultaneously and see the final result on the same screen like in Knockout.js tutorial http://learn.knockoutjs.com/#/?tutorial=intro. But of course it is not critical. As I said, debugging and testing process was very smooth.


The level of detail given by the stacktrace was not enough to diagnose the issue. Please see the stacktrace above. Maybe you should provide more details on debugging the auto generated classes, it looks very reasonable for me.

Well, I was debugging, caught breakpoint, but got “Java Quit unexpectedly” so that “emulated” browser just closed when I tested json data retrieval. If you are using some IDE like Eclipse which do a lot of possibilities for debugging. While testing from maven scripts, it was very difficult to debug as parsing through crash dump and finding the reason was time consuming. Initially I had faced a problem with using the api in eclipse project, however after importing the annotation rendering api (net.java.html.json-0.7.5.jar) into eclipse, I was able to use the API easily into my IDE and the development/debugging and testing pace increased significantly. Also I did not find any default logging mechanism apart from the stacktrace generated.


No. I didn’t know how to debug, so I had to put System.out in some points to understand what was going on. Using BrowserBuilder instead of a real browser didn’t help. For every change I made I had to recompile and launch BrowserBuilder, and there are the issues I wrote on Task2 about recompile errors I usually get.

Name at least three ways (or more) we can improve the documentation

  1. More simple language should be used.
  2. Some comprehensive examples.
  3. Definitely requires getting started tutorial.
  4. Maybe add some possibility to leave comments on the doc pages, so developers can discuss the issues.
  5. As I said above, I would like to have documentation for debugging applications of this type.


  1. Make sure that there are references to examples and explanation of particular class use.
  2. Explain usages and possible situation. It might be useful for every class.
  3. Add some code details which increase complexity into classes. From simple examples to more complex. That solves puzzle from pieces faster and motivates to use API.


  1. Specify clear prerequisites for the API: Maven, Knockout.js knowledge, some IDE that supports Maven projects.
  2. Provide consistent cross-referenced documentation with a clear starting point.
  3. For every API feature provide valuable example, from start to finish, not just pieces of code that were pulled out from some context.
  4. I still don’t understand how to use the API without Maven. Is it possible at all? Maybe you should consider adding some info on that.
  5. Maybe you should consider adding some information on internals of the library: at least some basic information on how it works.


  1. HTML has vast number of tags and events and properties, it is not possible to list all but currently documentation has so few code snippets for different elements. Although the online examples are very helpful and clear a lot of concepts.
  2. Add more information on annotations.
  3. Logging and error messages for runtime exceptions is a problem, a lot of time I had to browse through the whole of stacktrace to understand where the problem is.


  1. A complete example of using an external js library.
  2. Instructions of how to debug.
  3. How to deploy to a web container.
  4. Missing the @ on the Including JavaScript Libraries section (fixed)
  5. Example of how to consume a JSON that is not an array.

Compare this technology to others doing similar task. When would you prefer different rendering technology or language and why?

In fact, I haven’t much experience with html rendering technologies, because I am mostly a non-UI guy. But I have some experience with internal home-grown rendering technologies and they all were bad: difficult to use, maintain and test. Your API seems very powerful for me, but I am afraid, just for now I wouldn’t like use it in our production environment because of the lack of the documentation and the lack of personal experience with it. I am just simple not sure if I could do something that goes beyond the API examples.

Some other API available to render html pages using java are Java Server Faces API, CSSBox, Cobra & LoboBrowser (part of Lobo project), Flying Saucer Project. I would use Flying Saucer or LoboBrowser. Flying Saucer project provides an ability to render XHTML and with a pretty advanced features to filter with facilities of pdf, image, graphics conversion. LoboBrowser is full browser written in java that supports HTML4, Javascript and CSS and allows rendering at different levels. This again goes against the ease of simply importing an API versus switching to a different browser interface altogether.

I think the salient point of html4j is it's lightweight and ease of use. All I had to do was import a few libraries into my eclipse project, write shorter code using annotations, learn binding techniques (which has to be done anyways for all technologies) and get started, so maybe I would consider it. There is Cobra platform, it is also a lightweight API which enables html4, Javascript & CSS rendering. But I won’t choose it because of their documentation is not elaborate and online samples are limited.

At the current stage I wouldn’t use this framework. You have to show upfront how to do two very important tasks that I didn’t learn:

  • How to integrate with a real use case scenario: show how to deploy to Tomcat, how/when do I applyBindings?
  • How to debug properly: easy of debugging is a critical aspect for me.

I can’t choose something certain for now, but I believe I choose something with a comprehensive documentation and support (community as well as vendor). The support can be a crucial factor. For example when I searched for a problem for this API there were very few or no results at all. Also, I am not sure about security of the API. How to secure a REST call? Security is very important for me and my clients.


If I would need to go with pure js, then it would be just plain Knockout and separate backend on php, java or python (rest service). From my personal experience, it’s the best glue between Java/PHP and js, because of clear separation of concepts, so we could test and maintain the parts without much effort.

Conclusion

Good review. It shows the common problems people run into (Maven, Eclipse, debugging) as well as misunderstanings (this is not a JavaEE technology, but client one). There are clearly things that should be better documented and explicitly explained.

We use the feedback to make the API more usable.

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo