Win a copy of Machine Learning Systems: Designs that scale this week in the Scala forum
or Xamarin in Action: Creating native cross-platform mobile apps in the Android forum!

Tim Holloway

+ Follow
since Jun 25, 2001
Tim likes ...
Android Eclipse IDE Linux
Long-time moderator for the Tomcat and JavaServer Faces forums. Designer and manager for the enterprise server farm, which runs VMs, a private cloud and a whole raft of Docker containers.

These days, doing a lot of IoT stuff with Arduinos and Raspberry Pi's.
Jacksonville, Florida USA
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads
Scavenger Hunt
expand Rancher Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Tim Holloway

I think that's unnecessarily complicated. You'll almost always have static resources, so stuff in src/main/webapp. And since that entire subtree gets copied - including src/main/webapp/WEB-INF/web.xml (which is not in the classpath) and src/main/webapp/WEB-INF/classes, you have an exact image of what non-compiled resources are going to go into the WAR and not have to remember "this from Column A and that from Column B".
4 hours ago

Stephan van Hulst wrote:That's because Maven doesn't copy anything from the src/main/java folder. It just tells the compiler that's where the source files are, and that the compiler should put the compiled files somewhere else. Since XML files aren't compiled, they don't result in files anywhere else.

Put your XML file under src/main/resources. Maven is configured by default to treat this directory as a source directory from which it will copy the contents to the target.

Actually, don't.

Put it under src/main/webapp. The src/main/resource directory is what's used for JAR files. The src/main/webapp subtree will be copied verbatim into the WAR by the Maven WAR plugin. For example, to configure log4j, you'd have a src/main/webapp/WEB-INF/classes/log4j.xml file (or if you prefer,
11 hours ago
A "genius" manager is, as I implied, one who sets rules arbitrarily. Because in his infinite wisdom, he is Right. This is almost the opposite of what is considered to be the ideal manager, who may or may not know anything technical at all, but knows enough to avoid dis-incentiving his team. Good IT people don't have to be driven, since they'll drive themselves harder than anyone with a whip could drive them, so long as they're not discouraged.

But the "genius" hears some snippet of knowledge and makes an absolute and inviolable Law out of it. Thou Shalt Not this, Thou Shalt Not That, Thou Absolutely Must do This. Often they have detailed reasons for these rules, which, alas, often are based on incomplete understanding and/or outdated information. And often, it isn't actually the manager who's doing this, but some senior architect type who the manager looks to to determine what the Law Must Be.

It's not that we're into complete anarchy here, but we are into Best Practices. Best Practices are simply strategies that have stood the test of time, and they're not Inviolable Law, because sometimes the practice that actually works best for a specific case isn't what works best for a particular situation at a particular shop. The key is to keep to standards where possible while not forbidding exceptions when the standards would do more harm than good. For example, by making program logic excessively complicated and/or inefficient, or by hampering the productivity of  the developers and maintainers.

To make our position at the Ranch plain, we used to have a bot that would automatically flag the word "should" in messages and link to our "Did you just 'should' me?" FAQ entry. I think it finally got turned off because not every use of the word "should" in English is actually a command, but the idea was to make sure that we didn't get too authoritarian in our advice. Because in the end, that's what we're here for: advice. Not ready-made solutions, not cookbook recipes, but advice on how best to do what needs to be done, based on our own knowledge and experience.

It's no crime to be inexperienced. We're here to help with that. But we do our best work when everyone's pulling together. When we say "this works" and the boss says "you can't do that", and the work-arounds are awful, we'll say so. And if the work-arounds are either impossible within the constraints of the framework or prohibitively expensive, we'll say so as well. And in cases where someone does come up with a graceful solution, we will, I hope, be gracious enough to add that to our knowledge base and be thankful.

If someone comes to me with a problem with their login system and it's an in-house designed system that either they or the resident security "genius" invented, I'm going to give the standard lecture about how about 95% of all user-designed web security systems can be cracked in 15 minutes or less by non-technical personnel (based on my experience with a lot of financial and even some military systems, as well as similar experiences from other ranchers) and that it's much wiser to use the system invented by full-time trained security professionals and integral to JEE, but having done so, I and my partners in crime here on the Ranch will do our best to resolve the issue presented to us.

As I said previously, your main problem is that you're trying to fit a data structure that's essentially 3-dimensional into a display framework intended for 2 dimensions and the only clean and easy way to do that is to remap it into a 2-dimensional model. In Java this is not all that expensive, since 2 different maps of the same set of objects only carry the overhead of the relationships, and not the objects themselves. And, as you probably noted, I've a mechanism where the mapping only needs to be done when the data and relationships change, since once the model object is created, I cache it for re-use.
2 days ago
It's entirely up to you. The search entry on a webpage is often in a mini-form independent of whatever other form(s) might be on the page - especially when you're talking validating frameworks such as JSF, where a form cannot be accepted if any other value in the form is invalid.

You attach that form to backing logic that takes the data that was entered and searches according to whatever rules you wish. It could be a simple SQL query, a set of queries on multiple tables or a free-form search. In the case of free-form text queries like the forum search feature on the JavaRanch, it's common to use an engine such as Apache Lucene.
Great Chthulhu preserve us from "genius" managers and architects who place unnatural constraints on projects based on misunderstood concepts.     

A table is a 2-dimensional construct. It has rows and columns. The table data model is precisely what its name says - a Model of the data that the table will display. Therefore the model must also resolve to rows and columns.

Maps are not tables. They don't have rows and columns, they have keys and values. And, in your case, the values aren't scalars, they are vectors. That is about as non-flat a setup as anyone could find without severe straining. In fact, the graphical equivalent of your data is more like a table where one of the cells is a sub-table.

It is possible to nest tables in JSF, but not easily. It requires considerable fudging, because unfortunately JSF wasn't designed to support it, and while I hope that some day it will, that day isn't expected any time soon.

On the other hand, PrimeFaces is one of several JSF extensions that does permit collapsing a table based on a common element value, so you can get something like what you're envisioning by using PrimeFaces. But Primefaces is expecting - or rather demanding a flat table datamodel. If your primary datamodel does not conform, then it is your responsibility to construct a GUI datamodel that conforms to what Primefaces requires.

It is, incidentally, a common fallacy that when you have an ORM datamodel that that datamodel should always directly serve as the JSF GUI datamodel. They are 2 different types of models, serving 2 different purposes. It's convenient when you can make one set of objects serve for both purposes, but not always possible. A very common situation where that occurs is when you have a DBMS that doesn't have a native boolean data type but you want checkboxes on a JSF form. Because the get/set methods for checkboxes have to be boolean methods or JSF will refuse to work with them. Thus it is sometimes required to construct a façade object to serve as the GUI datamodel.

2 days ago
I don't think so. The dataTable wants flat data. Your data isn't flat.

There's nothing wrong with creating a UI model helper class - unless you're forbiddent to do so by an idiot employer. Most IDEs make it very easy to generate simple javabean classes via a code wizard.

You don't even need to create a separate class file, since this is something used only within the backing bean.
2 days ago
Welcome to the JavaRanch, Carl!

Basically, you need a data model whose structure is something like this:

I've omitted the grunt code (constructors, getters/setters) for clarity. You'd then build a collection (for example an arrayList) of ModelStats and a DataModel to wrap it. That is,

Since you're doing a tabular display, the View Template would follow the following form:

You have 2 choices for MAGIC_STUFF.

The first, and easiest overall is to add an aggregating property-get method to format the numbers as a single String that can be rendered via an h:outputText. That is:

This code may require tweaking, since you're dealing with a list of integers here.

The second method can be done without hacking the model element class:

As coded, this would print a trailing comma, but I think that you can use the ui:repeat varStatus attribute to control that.

The ui:repeat and h:dataTable are a lot alike, but h:dataTable renders as a 2-dimensional object with the elements arrayed in rows, whereas ui:repeat simply repeats its contents verbatim, leaving it up to you to do the actual layout. Also, h:dataTable employs a DataModel that can be queried in action code to determine which row the link, button, or AJAX control that was fired is in.
2 days ago

I forget where I got this. And the version numbers may be old. You may need to do some dependency foo, since it was rather sensitive to the versions of the components that interacted with it as I recall.

Note that there are 2 dependencies here. The slf4j API provides the standard interceptors for the different loggers. Then the slg4j log4j12 backend routes them through log4j. Other backends can also be used if you prefer to write your logs via some other logging framework.
2 days ago
Well, first, I don't recommend actually returning the raw data as a value to a dataTable.

In order to manage the rendering process, a dataTable needs a corresponding DataModel object as a wrapper (façade). In the case where you simply return a raw array or collection of data, JSF must construct an anonymous DataModel automatically. Nothing inherently wrong with that, except that the DataModel happens to have some properties that are very useful.

In particular, the getRowData method, which can return the data of a selected row (for example, the row in which you clicked a button or link), and the getRowIndex method, which returns the 0-based index of the selected row.

If you construct your own DataModel object, wrap it around your raw data and return that as the value property, you will have done the same thing that JSF did anyway, but now you have an object that your action methods and AJAX listeners can use to understand context without having to fumble through a bunch of unnatural and awkward circumventions. DataModels are easy to use. Just construct them and make them available via property-set. You don't have to re-wrap the data if the data changes unless you completely replace the data collection object with a new object. Changes to data within a collection don't require re-wrapping it.

Which brings me to the second point. The collection that the dataTable represents must be a sequential collection. That is, a List, array, or other collection that has a natural order. Yes, you can enumerate any collection, but the order in which the elements of that collection are returned must be precisely defined. In the case of a hash, changing even one element can completely scramble the order of the returned items. It's also worth nothing that the collection must return the exact same sequence multiple times (be idempotent), since JSF may call the value "get" method up to about 6 times for a single page request. And thus, also, you don't want to do any expensive operations such as database access in the data set while its value get method is executing.

And now to the specifics. A HashMap internally is a collection of key/value pairs. So when you enumerate the map, what the enumerator is actually returning on each element is an internal object containing one key, one value, and possibly some overhead (such as a hash collision link). That object doesn't implement a useful toString() method since it's not intended to be used directly. Besides, a dataTable usually has multiple columns, so you need to indicate what data goes in what column.

Oh. And one more thing. You're returning a collection containing multiple sub-collections. A dataTable only maps the primary collection. You'll need to flatten out the model to deal with that.

So here's some possibilities.

First, consider an ordered collection as the basis for your dataTable Model. Secondly, make the model elements be something that JSF can deal with as objects with properties or can convert to an array of Strings. In the case of a Map, what I'd normally do is construct a List or Array containing Map elements as user-defined objects, but here's one alternative:

Hopefully you can translate your getUserLogins method to build the login Record List. That's more work than I can justify for this example.

Note that this code has the very useful property that if your model becomes outdated, you can simply set loginRecordModel to null and a fresh model will be built the next time it's needed. That also handles the initial construction more gracefully than trying to do so in the backing bean constructor (which often doesn't have enough context) or a @PostConstruct method.

And now, finally, the dataTable:

Actually, there's something odd about your datatable elements, but since I don't work regularly with PrimeFaces, I'm not sure exactly how to lay it out.

And finally, since this is the sort of thing where you'd like to be able to expand/collapse and/or highlight rows by the major key (loginId), PrimeFaces does have an easy way to do that, but that, too is beyond the scope of this example.

Incidentally, I cheat. I've defined a set of boilerplate snippets in my IDE to handle the grunt work of setting up the dataModel and building its payload because I've done it so often.
2 days ago

Campbell Ritchie wrote:

Tim Holloway wrote:. . . þe letter þorn.

Don't ðey still use at letter in Iceland?

Þaet's an eð It entered þe English language later - þorn was derived from runic, which was derived from Greek. Þe letter eð seems to be a later Roman counter-proposal which died out earlier of its own accord. It took an international conspiracy of type-foundaries to kill þorn, þough.

Icelandic has kept both letters, it appears. Þen again, þey also are more like Old English. Whence we got such words as "wind-eye". Or, more corruptly, "window".
3 days ago
Yes, that's a problem in complex systems that use libraries from many sources. A log aggregator such as slf4j can handle the job of re-routing all those other log API requests into log4j.
3 days ago

Jan de Boer wrote:Ah, yes, that seems to be correct. I think pi is mostly just written as the greek letter: π. (I hope that renders correctly..)

Yeah. I had to write it out. It doesn't seem to be attached to any of my extended keys.

But at least I'm set if the English language ever brings back þe letter þorn.
3 days ago
I went back and checked on this and the whole capitalization/greek/Hebrew symbology is  pretty much ad hoc for the author.

But lower-case "e" is Euler's constant, so physicists prefer to avoid ambiguity by not using it for other purposes. I'm sure the same would be true for pi.
3 days ago
Isn't stuff like this why Gradle was invented?
3 days ago
Strange. Google doesn't know anything about "range accuracy". And I have no idea how streaming SIMD Extensions (SSE) is supposed to magically cure the precision problems inherent in binary floating-point. SSE is a performance feature. And only on certain hardware. A fundamental precept of Java is "Write Once, Run Anywhere", which negates hardware-specific solutions.

Floating-point numbers have Machine epsilon. That is the indicator of how precise a value can be for the machine quantity in question. At the epsilon level, you have an upper and lower bound to the possible actual value, but the true actual value is pure fuzz.

Computers cannot work with mathematical abstractions, only machine quantities. So live with it. There's a whole mathematical discipline of error analysis and it's fundamental to engineering and has been since slide rules and analog measuring instruments. Engineering specs are not considered complete without tolerances. And in many cases, those tolerances are far less than the epsilon uncertainty of common floating point implementations.

Computer output routines can and often do allow for the fuzziness of the data they are dealing with. That's what gives us a printed output of "6.1" when the actual bit-for-bit value of a float is more like 6.0000000000009976 or 6.0000000000010032.

But in the Real World everything has its limits and only a fool expects precision where there is none. Only in pure mathematics can you be 100% precise. And then only until you apply the mathematics to something tangible. You can complain that floating-point pennies don't balance a checkbook, but the minute you go from bookkeeping to accounting even pennies get fuzzy as interest-rate functions, currency conversions and the like chew on them. On the bookkeeping side, you have 2 choices: use BigDecimal (or something equivalent such as a hand-rolled Currency class) or scale floating-point up 2 orders of magnitude so that integral numbers of pennies actually register as integral values. People have done both.

Yes, I'd like to be able to use a currency class that allowed mathematical operators, but so far no one has persuaded the architects of Java to permit operator overloading, and mathematical operators in Java apply only to primitives, not classes.

If your real gripe is that you cannot add and subtract money, consider COBOL. It has no such problems. It was designed for it. But here also, consider that not every country on Earth has only 2 decimal places to their units of specie.

4 days ago