Per Lindberg

Ranch Hand
+ Follow
since Jan 17, 2008
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
2
Received in last 30 days
0
Total given
7
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Per Lindberg

Keeping the Map that has the logged-in session ids and usernames in application scope is an interesting alternative to a static member of the HttpSessionListerner, but does not buy much.

The main problem is to detect logins (and logouts/expired sessions). There seems to be no simple way of doing that.

9 years ago
I too have been wrestling with this kind of problem recently. I need to keep track of when users log in, and which logged-in sessions there are.

There seems to be no simple way to do this in a Java EE servlet environment (like getting a callback for all logins).

I finally managed to solve it by using a combo of a HttpSessionListener and a Filter.
The HttpSessionListener keeps track of all logged-in sessions in a static Map. Note: not all sessions are logged-in, and ONLY logged-in sesions gets call to sessionDestroyed! (Or is that a bug in Glassfish 3.1.2.2?)
The Filter then fills in username.
Quite hairy. I can post code if anyone is interested.

Shouldn't there be a simpler way?
9 years ago
It appears that there's something fundamentally wrong with the new @MultipartConfig annotation.

The documentation says nothing about where temporary files are stored. All the javadoc
http://docs.oracle.com/javaee/6/api/javax/servlet/annotation/MultipartConfig.html#location()
has to say is:

The directory location where files will be stored. Default:""


Huh? What, exactly, is the location "" ?? Root? Current path?

And the JEE 6 tutorial is not terribly helpful either:
http://docs.oracle.com/javaee/6/tutorial/doc/gmhal.html

location: An absolute path to a directory on the file system. The location attribute does not support a path relative to the application context. This location is used to store files temporarily while the parts are processed or when the size of the file exceeds the specified fileSizeThreshold setting. The default location is "".


Not terribly illuminating.

Now, suppose that this directory can't be written to. Then the servlet won't work. Or suppose that the directory is unsuitable for some other reason. Then the programmer can hard-code a path using the location attribute. But hold on: the webapp may need to run on different platforms (say, Unix and Windows). Then the temp directory must be configurable. But that can't be done using the @MultiPart annotation (afaik). Eek!

A sensible catalog would be to use the System Property "java.io.tmpdir". That should imho be the default, not some undocumented absolute path named "".

Is there any way of setting location to ${java.io.tmpdir} ??
If not, shouldn't the applicable JSR be amended?


9 years ago
I no longer want to use roles for authorization. So I want to get rid of all 'role' stuff in my web.xml .
I still want to have <transport-guarantee>CONFIDENTIAL, of course.

Now, the surrounding<security-constraint> must have a non-empty <auth-constraint>, which in turn requires at least one declared <security-role>.

I think that it would be logical to just specify <auth-constraint>*</auth-constraint>, and then no <security-role> has to be specified (and the user don't need any role), but that appears to be wrong at least in Glassfish.
So... is it true that you can't get rid of roles entirely if you need HTTPS?

10 years ago
I have now received a good reply from the GlassFish Server Documentation Team and Engineering Team:

"GlassFish Server always provides both a transactional version (JTADataSource) and a nontransactional version (NonJTADataSource) of a data source to a JPA provider. Typically, users specify only JTADataSource and GlassFish Server uses an internal API to obtain a NonJTADataSource version of it.

It should be OK to just change the jdbc-connection pool attribute non-transactional-connections to "false", which is the default value for this attribute. "

So your guess is correct for Glassfish too, James. Thanks!

James Sutherland wrote:Yes, you should configure a sequence connection pool that uses a non-JTA DataSource.



Yes, but do you mean a an extra separate connection pool, or could I just re-configure my existing connection pool to be non-transactional-connections="true"?
Curiouser and curiouser!

You're right that I don't need another Persistence Unit, Glassfish will automagically create one extra for me:
http://www.java.net/node/676242

Now, according to the EclipseLink FAQ, you must "Ensure a sequence connection pool is being used if using TABLE sequencing":
(http://wiki.eclipse.org/EclipseLink/FAQ/JPA#How_to_diagnose_and_resolve_hangs_and_deadlocks.3F)

and you must also configure that special extra separate connection pool as a eclipselink.connection-pool.sequence.

(http://www.eclipse.org/eclipselink/api/2.3/org/eclipse/persistence/config/PersistenceUnitProperties.html#CONNECTION_POOL_SEQUENCE)

Or... should I just reconfigure my existing connection pool...?

James Sutherland wrote:For a sequence connection pool you don't need another persistence unit. You do need a non-JTA data-source, but most servers allow you to use the same connection pool for JTA and non-JTA.



Per Lindberg wrote:
Aha, ok. So in the example below, I just have to change non-transactional-connections from "false" to "true", and that's it?



Hmm...
The Wikibooks article (under 'Concurrency and deadlocks') says that:

"...if you use a JTA data-source connection, it is important to also include a non-JTA data-source connection in your persistence.xml."

So, don't I need both a changed jdbc-connection-pool (with non-transactional-connections set to true) and an extra
<non-jta-data-source>jdbc/whatever</non-jta-data-source>under <persistenced-unit name="blah"> in persistence.xml?

James Sutherland wrote:For a sequence connection pool you don't need another persistence unit. You do need a non-JTA data-source, but most servers allow you to use the same connection pool for JTA and non-JTA.



Aha, ok. So in the example below, I just have to change non-transactional-connections from "false" to "true", and that's it?

<jdbc-connection-pool
name="fpdb-pool"
datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"
res-type="javax.sql.DataSource"
non-transactional-connections="false"
allow-non-component-callers="true">
<property name="user" value="..."/>
<property name="password" value="..."/>
<property name="port" value="3306"/>
<property name="databaseName" value="fpdb"/>
<property name="serverName" value="localhost"/>
<property name="url" value="jdbc:mysql://localhost:3306/fpdb?useUnicode=true&characterEncoding=utf8&characterResultSets=utf8"/>
</jdbc-connection-pool>

<jdbc-resource pool-name="fpdb-pool" jndi-name="jdbc/fpdb" enabled="true" object-type="user"/>


James Sutherland wrote:For the pre-allocation, a bigger size is recommend if you do lost of inserts. Note that for IDENTITY sequencing the id must be selected on every insert, so your ratio of 1:50 would be 50:50 for IDENTITY, TABLE sequencing is much more efficient.



Right!

James Sutherland wrote:Not sure why you would be worried about losing 50 sequence numbers on a restart?



This could be debated at length. :-) Allow me to just say 'because of aestetics'. I like it. And it does help somewhat when troubleshooting. Also, in my case the MySQL server is restarted quite often. Sure, with tables that gets zillions of updates at a time, that's another matter entirely. No argument there.

James Sutherland wrote:If you are using EclipseLink, you can use a sequence connection pool...


Does this mean that I must set up both another Persistence Unit (in persistence.xml) and another JDBC Connection pool (using asadmin add-resources foo.xml with an extra <jdbc-connection-pool non-transactional-connections="true" ...> plus an extra <jdbc-resource>)?

James Sutherland wrote:Also use a large sequence pre-allocation size.


Right, at least for tables that gets losts of inserts (like my case with millions of inserts). However, the EclipseLink default value of allocationSize appears to be 50, which even with millions of inserts at a time would give a negligable overhead of 1:50 (2%), I guess. And in the case of tables with few and seldom inserts, allocationSize=1 seems nice to me, otherwise each redeploy or restart would bump the next id with 50.
Thanks, that's the kind of answer I was hoping for!
However, sometimes I do mass updates with millions of new records. The note about potential concurrency problems in the Wikibooks article sounds scary. Perhaps a separate id table for each id is needed for such cases...?
A canonical design is to provide each Entity with a unique id and create the id column with AUTO_INCREMENT.

But this isn't safe with MySQL, since it doesn't store the next free id, just re-calculates it at restart as (highest + 1). So if you delete the latest entity, restart MySQL and then create a new entity, the id will be re-used. This is a bug in MySQL (#199) that has been known since at least 2003. The MySQL folks appears to have just documented the behaviour and then ignored it.

This can have far-reaching and catastrophic consequences, since id:s are not guaranteed to be unique. (Think "data warehouse with snowflake schema").

Is there a nice way to tell JPA2 to circumvent this horror? For example by using a dedicated table for 'next free id:s'? Or something?

Here's the way I do it now:

@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() { return id; }
public void setId(int id) { this.id = id; }

CREATE TABLE IF NOT EXISTS foo (
id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
...
) ENGINE=InnoDB;

Agreed. Hiding the the bean in e.g. tag context would be cleaner.
And, of course, if you only need one instance, then jsp:useBean is The Right Thing.
Any other neat alternatives?
10 years ago
JSP
And if you're not so strict about using only JSTL:

This example creates a Map specifying columns to hide (later).

It has the advantage that it can be included several times in the same JSP, since jspUseBean does not tolerate duplicate id:s.
(Another way might be to use a JSP tag file).

10 years ago
JSP