[JBoss AS7 Development] - multiple entitymanager, entity mix-up.
by gwa
gwa [http://community.jboss.org/people/gwa] created the discussion
"multiple entitymanager, entity mix-up."
To view the discussion, visit: http://community.jboss.org/message/633610#633610
--------------------------------------------------------------
Hello,
I'm evaluating JBoss 7 on some project, but I'm facing an issue :
I'm using Spring to initialize my entityManager (JPA provider : Hibernate):
<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>classpath*:META-INF/persist.xml</value>
</list>
</property>
...
</bean>
The persist.xml file are in jar file in WEB-INF/lib (there are several jar with persistence unit and for instance, user.jar defines the user-pu, order.jar defines the order-pu, ...).
My entities are listed in orm.xml file. for each persist.xml file, there is one orm.xml file in the same location.
Now, here the full log on hibernate :
DEBUG: org.hibernate.ejb.Ejb3Configuration - Processing PersistenceUnitInfo [
name: user-pu
persistence provider classname: org.hibernate.ejb.HibernatePersistence
classloader: ModuleClassLoader for Module "deployment.my-ear-1.32.0.ear.my.war:main" from Service Module Loader
Temporary classloader: org.springframework.instrument.classloading.SimpleThrowawayClassLoader@653838e4
excludeUnlistedClasses: false
JTA datasource: null
Non JTA datasource: org.jboss.jca.adapters.jdbc.WrapperDataSource@5626b468
Transaction type: RESOURCE_LOCAL
PU root URL: vfs:/content/my-ear-1.32.0.ear/my.war/WEB-INF/lib/user-1.32.0.jar/
Shared Cache Mode: UNSPECIFIED
Validation Mode: AUTO
Jar files URLs []
Managed classes names [
my.package.user.UserEntity1 <-- defined in user.jar
my.package.user.UserEntity2 <-- defined in user.jar
...
my.package.order.OrderEntity1 <-- defined in order.jar
...
The user-pu manage entities from user jar but also SOME (not all) other entities from other jar...
The other persistence unit define no entity :
DEBUG: org.hibernate.ejb.Ejb3Configuration - Processing PersistenceUnitInfo [
name: order-pu
persistence provider classname: org.hibernate.ejb.HibernatePersistence
classloader: ModuleClassLoader for Module "deployment.my-ear-1.32.0.ear.my.war:main" from Service Module Loader
Temporary classloader: org.springframework.instrument.classloading.SimpleThrowawayClassLoader@2aa20aac
excludeUnlistedClasses: false
JTA datasource: null
Non JTA datasource: org.jboss.jca.adapters.jdbc.WrapperDataSource@5626b468
Transaction type: RESOURCE_LOCAL
PU root URL: vfs:/content/my-ear-1.32.0.ear/my.war/WEB-INF/lib/order-1.6.jar/
Shared Cache Mode: UNSPECIFIED
Validation Mode: AUTO
Jar files URLs []
Managed classes names []
Mapping files names []
Properties []
So "Unknown entity" error pop on every entityManager but the one associated with user-pu. (the first pu).
Is someone have already faced such issue?
Is there a magic properties into JBoss to fix that?
Thank you
--------------------------------------------------------------
Reply to this message by going to Community
[http://community.jboss.org/message/633610#633610]
Start a new discussion in JBoss AS7 Development at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&cont...]
13 years, 3 months
[JBoss Transactions Development] - dynamic reconfiguration
by Jonathan Halliday
Jonathan Halliday [http://community.jboss.org/people/jhalliday] created the discussion
"dynamic reconfiguration"
To view the discussion, visit: http://community.jboss.org/message/623969#623969
--------------------------------------------------------------
The configuration mechanism in JBossTS has evolved over the years, most recently to use a set of javabeans to hold the myriad config values. There are a dozen or so EnvironmentBeans, roughly one per module, and a central repository (BeanPopulator) that holds a singleton instance of each. The singletons are instantiated on demand with initial values populated from an embedded properties file or system properties. These defaults can then be overridden programatically, either by a bean wiring framework using xml (as in older JBossAS transaction-jboss-beans.xml) or in java code using the bean's setter methods (as in AS6 ArjunaTransactionManagerService etc). So far so good - this approach provides type safety for the values as well as compatibility with modern DI frameworks and is a big improvement over what we has before.
It still has one significant shortcoming though: once the transaction system is initialized, any subsequent config changes are ignored. That would not be so bad, except that the initialization can happen very early. Specifically we have a lot of static initializers that read and cache config values at class load time. e.g.
{code}
public class SomeThing
{
private static final boolean XA_TRANSACTION_TIMEOUT_ENABLED;
static
{
XA_TRANSACTION_TIMEOUT_ENABLED = jtaPropertyManager.getJTAEnvironmentBean().isXaTransactionTimeoutEnabled();
}
public void doThing()
{
XA_TRANSACTION_TIMEOUT_ENABLED ? thing() : otherThing();
}
}
public class jtaPropertyManager
{
public static JTAEnvironmentBean getJTAEnvironmentBean()
{
return BeanPopulator.getDefaultInstance(JTAEnvironmentBean.class);
}
}
public class BeanPopulator
{
private static final ConcurrentMap<String, Object> beanInstances = new ConcurrentHashMap<String, Object>();
public static <T> T getDefaultInstance(Class<T> beanClass) throws RuntimeException {
return (T) beanInstances.get( beanClass.getName() );
}
}
{code}
This provides very fast runtime execution, but a call to e.g.
{code}jtaPropertyManager.getJTAEnvironmentBean().setXaTransactionTimeoutEnabled(true);{code}
must come before the classload of SomeThing if it's going to have any effect.
So what are the alternatives?
Option A:
{code}
public class SomeThing
{
public void doThing()
{
if(jtaPropertyManager.getJTAEnvironmentBean().isXaTransactionTimeoutEnabled())
{
thing()
}
else
{
otherThing();
}
}
}
{code}
looks attractive at first glance. However the system is now so highly tuned that the runtime overhead of the underlying hashmap lookup for
{code}beanInstances.get( beanClass.getName() );{code} is going to cause significant performance impact, see e.g. JBTM-853.
Additionally, usage patterns of the form
{code}
public class SomeThing
{
public void doThing()
{
if(jtaPropertyManager.getJTAEnvironmentBean().isXaTransactionTimeoutEnabled())
{
thing()
}
unrelatedStuff();
if(jtaPropertyManager.getJTAEnvironmentBean().isXaTransactionTimeoutEnabled())
{
relatedThing();
}
}
}
{code}
will need to be hunted down and replaced with
{code}
public class SomeThing
{
public void doThing()
{
boolean cachedConfig = jtaPropertyManager.getJTAEnvironmentBean().isXaTransactionTimeoutEnabled();
if(cachedConfig)
{
thing()
}
unrelatedStuff();
if(cachedConfig)
{
relatedThing();
}
}
}
{code}
including all the more complex cases where the usages are in the same call chain but not necessarily the same method, class or even package.
Option B:
{code}
public class SomeThing
{
private final ConfigBeanHolder config;
public SomeThing(ConfigBeanHolder config)
{
this.config = config;
}
public void doThing()
{
if(config.getJTAEnvironmentBean().isXaTransactionTimeoutEnabled())
{
thing()
}
unrelatedStuff();
if(config.getJTAEnvironmentBean().isXaTransactionTimeoutEnabled())
{
relatedThing();
}
}
}
{code}
which eliminates the expensive hashmap operation and potentially allows us to do nifty stuff like running multiple different configurations in parallel e.g.
{code}
jtaThing = new SomeThing(jtaConfig)
jtsThing = new SomeThing(jtsConfig)
if( needDistributedTx ) {
useThing( jtsThing );
} else {
useThing( jtaThing );
}
{code}
However, we would need to retrofit the entire codebase with suitable constructors as well as hunting down the repeated usages of the same parameter as mentioned for the previous option.
Option C:
{code}
public class SomeThing
{
private static boolean XA_TRANSACTION_TIMEOUT_ENABLED;
static
{
XA_TRANSACTION_TIMEOUT_ENABLED = jtaPropertyManager.getJTAEnvironmentBean().isXaTransactionTimeoutEnabled();
jtaPropertyManager.getJTAEnvironmentBean().registerPropertyChangeListener(
new PropertyChangeListener() {
public void propertyUpdated(String name, Object value) {
if("XA_TRANSACTION_TIMEOUT_ENABLED".equals(name) {
XA_TRANSACTION_TIMEOUT_ENABLED = value;
}
}
}
}
public void doThing()
{
XA_TRANSACTION_TIMEOUT_ENABLED ? thing() : otherThing();
}
}
{code}
which should be fairly quick at runtime but introduces a lot of boilerplate code and still suffers from some of the problems identified for other options.
There are additional concerns that affect all options. For example, some properties cannot be considered in isolation as they interact with others:
{code}
public class SomeThing
{
private Object someProperty;
private Object relatedProperty;
public boolean isConfigValid()
{
return someProperty.equals(relatedProperty);
}
}
{code}
maintaining validity in the face of mutability would require e.g.
{code}
public class SomeThing
{
private final ImmutableConfigHolder config;
public void updateConfig(ImmutableConfigHolder replacementConfig) {
config = replacementConfig;
}
public boolean isConfigValid()
{
return config.getSomeProperty().equals(config.getRelatedProperty());
}
}
{code}
which given the complex interrelationships between properties may bean we can't effectively decouple individual module's configs from one another any more and wind up with a single huge environment bean containing all the properties.
Finally, we need to consider the problems that arise in trying to support a system that is reconfigurable. The content of the properties file is no longer sufficient to determine the runtime config. To diagnose or reproduce issues we'd additionally require either a comprehensive log of runtime property changes or individual error log messages to be retrofitted to contain a dump of any relevent config option values.
The final option is a bit of a wildcard: don't change anything in the JBossTS codebase at all. Instead, use the JBossMC module system to effectively isolate multiple copies of the transaction system with different configs and hot swap between them to effect a config change. That's not without its problems, particularly where recovery is concerned, but they may turn out to be more tractable or at least less labor intensive than solutions that require wholesale audit and refactoring of the entire JBossTS codebase. On the other hand if we plan to substantially refactor the codebase anyhow then making changes to the config system along the way may not be so bad.
We can also potentially tackle the issue on a property by property basis, giving priority to those options for which dynamic reconfiguration has most benefit. Or go for a more limited objective of keeping the config static but delaying its effective freeze beyond classloading time, for example by requiring an explicit lifecycle with an instantiate/start step that snapshots the config values at that point and builds the system using them.
Thoughts?
--------------------------------------------------------------
Reply to this message by going to Community
[http://community.jboss.org/message/623969#623969]
Start a new discussion in JBoss Transactions Development at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&cont...]
13 years, 3 months
[JBoss Remoting Development] - SASL and Kerberos
by Darran Lofthouse
Darran Lofthouse [http://community.jboss.org/people/dlofthouse] modified the document:
"SASL and Kerberos"
To view the document, visit: http://community.jboss.org/docs/DOC-17302
--------------------------------------------------------------
Working on how Kerberos can be supported with Remoting for https://issues.jboss.org/browse/REM3-29 REM3-29, the first stage is understanding the unederlying mechanism.
Whilst there is some JDK documentation this does not go into the finer details, the implementation makes quite a few assumptions so this article is to capture the additional detail.
h1. Client
OS local Kerberos configuration can be used to specify the Ream and KDC, alternatively JVM wide system properties can be used: -
System.setProperty("java.security.krb5.kdc", "ec2-?-?-?-?.compute-1.amazonaws.com");
System.setProperty("java.security.krb5.realm", "DARRANL.JBOSS.ORG");
On the client side unless you fallback to default JAAS configurations the SASL negotiation needs to be within a PrivilegedAction where a Subject for the local clients identity is passed in: -
Subject.doAs(clientSubject, new PrivilegedAction<Void>() {
@Override
public Void run() {
try {
client.haveAChat();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
});
To obtain the subject a JAAS LoginContext is used with the 'com.sun.security.auth.module.Krb5LoginModule' LoginModule, although JAAS is used we don't need the configuration within a descriptor - we can provide a simplified configuration for the client and dynamically configure the LoginContext.
No special configuration of the LoginModule is required on the client side. There are three configuration options for the client: -
1. Use a supplied CallbackHandler to prompt the client for the username and password, the LoginModule will then obtain their Kerberos tickets.
2. Configure to use a keytab without prompting - useful for unattended processes e.g. server instances.
3. Configure to use local OS cache i.e. if user obtained Kerberos ticket on OS log on use this identity.
The client side does not require the 'storeKey' option being set to true although if a process is both a client and a server this can be set to true.
Inside the PriviledgedAction the SaslClient can be obtained as: -
Sasl.createSaslClient(MECHS, null, "remoting", "test2", Collections.EMPTY_MAP,
new NoCallbackHanlder());
The parameters are: -
1. Array of mechanisms, in this case just "GSSAPI"
2. The authorization ID, if not supplied it will default to the username@REALM of the user.
3. Protocol
4. Server host name
5. Configuration options
6. Callback Handler
*The values for protocol and server host name are criticial to the negotiation process.*
In this example before the communication with the server commences the client side will automatically send a TGS-REQ to the KDC for the server name 'remoting/test2' - this is an integral part of the process an if this server is not known by the KDC the process will terminate.
For this TGS-REQ a service principal mapping on the KDC is sufficient, however there are also issues on the server side of this to consider.
There are a couple of options which could be passed in, one is to enable server_auth, this setting means that in addition to the server verifying the identity of the client the client will also verify the identity of the server.
At the stage of the SASL message exchange the CallbackHandler on the client is not required to handle any callbacks, the client side idenity has already been established when the Subject was obtained.
If this was SPNEGO the web browser would be verifying the DNS name of the server it is connecting to, we should consider if our client should allow any flexibility in the setting of server host name or should we mandate that it does match the host name we are connecting to - at the same point also consider banning connection to IP addresses as DNS is also fundamental to this.
h1. Server
As for the client side the Realm / KDC configuration is required, again this can either be configured using OS specific configuration or the same system properties can be set.
On the server a Subject needs to be obtained similar to how one was obtained for the client, this time the Subject is for the identity of the server - all the Sasl calls will then be within a PriviledgedAction.
When the Subject for the server is obtained here it is essential that 'storeKey' is set to true for the LoginModule, this will store the KerberosKeys for the server in the PrivateCredentials of the Subject.
On the server side the SaslServer can be obtained with: -
SaslServer saslServer = Sasl.createSaslServer(GSSAPI, "remoting", "test2", Collections.EMPTY_MAP,
new AuthorizeCallbackHandler());
Here the parameters are: -
1. Chosen mechanism "GSSAPI"
2. Protocol
3. Server Host Name
4. Configuration options
5. Callback Handler
On the server side the protocol and server host name are again critical to the process but this time they affect how the PrivateCredentials of the Subject are searched.
In this example the protocol is 'remoting', the server host name is 'test2' and from the system properties the realm is 'DARRANL.JBOSS.ORG', the private credentials of the Subject will be searched for KerberosKeys with the prinicipal name " mailto:remoting/test2@DARRANL.JBOSS.ORG remoting/test2(a)DARRANL.JBOSS.ORG"
The server identity does need to match the identity the client received in the TGS-REP from the TGS-REQ that the client sent in, however I need to verify if the names within the Subject also need to match or if we can just allign the createSaslServer identity with what is provided in the Subject. The reason this needs to be considered is that it may be desirable to just have a single Kerberos identity on the server for both Remoting and HTTP, however for HTTP the identity may already be mapped to HTTP/test2
The only Callback that needs to be supported is the AuthorizeCallback, by default the authentication ID will be in the form username@REALM - there may be some desire to drop the @REALM part.
In the exchange between the client and the server we do need to be able to support 0 length SASL messages.
There is also an option that may be possible to set on the server side if the identity is only being used for incomming requests and that is to set isInitiator to false, this removes one round trip with the KDC.
--------------------------------------------------------------
Comment by going to Community
[http://community.jboss.org/docs/DOC-17302]
Create a new document in JBoss Remoting Development at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=102&co...]
13 years, 3 months