How can I add a datasource configuration file within a embedded Weblogic EJB Container?
As far as I know, this is only possible with a already installed and preconfigured weblogic, instance? Is this correct?
My configuration is the following:
Properties prop = new Properties();
prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("datasource.properties"));
EJBContainer container = EJBContainer.createEJBContainer(prop);
Context initialContext = container.getContext();
((MyEJB)initialContext.lookup("MyEjb")).writeInDatabase();
I have not found a lot of documentation on this topic.
http://vineetreynolds.blogspot.com/2012/11/the-embedded-ejb-container-in-weblogic.html
see if this helps, although I cant get stuff to run yet on my end
you are better of being in jpa land, and create a test persistence.xml that basically uses jdbc url/user/pass and not jndi
Related
Context: Existing JavaSE application written in Swing which fires up an embedded server (so far it was Jetty) but we need to switch to Java EE, so we thought about bringing in an enterprise container (candidates are: Payara, Tomee, Wildfly).
The server should be able to run a web app based on dynamic input: web context, with its own web.xml, specific web resources which are not known at build time, so uber jar is not really an option for us.
We have successfully started a web app on Payara using code like the following (this is not working code, but it shows the steps we took for using Payara)
GlassFish glassfish;
WebContainer container;
GlassFishRuntime glassfishRuntime = = GlassFishRuntime.bootstrap();
glassfish = glassfishRuntime.newGlassFish();
glassfish.start();
// Access WebContainer
container = glassfish.getService(WebContainer.class);
WebContainerConfig config = new WebContainerConfig();
container.setConfiguration(config);
Context context = container.createContext(contextPathLocation);
m_webAppContexts.put(p_contextName, context);
WebListener listener = container.createWebListener("listener-1", HttpListener.class);
listener.setPort(myDynamicPortNumber);
container.addWebListener(listener);
container.addContext(context, myDynamicContextPath);
context.addServlet(myDynamicMapping, myServletName);
This is all working and a basic web application starts in Payara when invoked from our Java SE application.
We also have a fragment of web.xml declaring additional servlets that we want to bring in this dynamic deployment if given conditions are satisfied.
What is the best way to override the existing web.xml with fragments from another web.xml? We need pointers to documentation, directions from more experienced Payara users.
This is not possible with Payara or Wildfly, as they work very differently from how Jetty works.
However, it is possible with Tomee.
We want to migrate an old application from Glassfish to TomEE. We encounter a problem about JNDI.
When I run the cmd for Glassfish server asadmin list-jndi-entries I get some JNDI entries:
java:global: com.sun.enterprise.naming.impl.TransientContext
UserTransaction: com.sun.enterprise.transaction.TransactionNamingProxy$UserTransactionProxy
com: com.sun.enterprise.naming.impl.TransientContext
OURAPPSERVER-Q2: com.ourcompany.product.OurAppServer
com.sun.enterprise.container.common.spi.util.InjectionManager: com.sun.enterprise.container.common.impl.util.InjectionManagerImpl
ejb: com.sun.enterprise.naming.impl.TransientContext
jdbc: com.sun.enterprise.naming.impl.TransientContext
AppServer: com.sun.enterprise.naming.impl.TransientContext
As you can see, there is AppServer JNDI entry. This entry is bind from our code manually.
try {
InitialContext context = new InitialContext();
context.rebind("AppServer/facede", this);
} catch (NamingException e) {
e.printStackTrace();
logger.severe("Unable to register the service facade bean, "
+ "JPOS will not be able to access services");
}
This code is not working in TomEE. I get some error like:
javax.naming.NameNotFoundException: Name [AppServer/facede] is not bound in this Context. Unable to find [AppServer].
at org.apache.naming.NamingContext.bind(NamingContext.java:899)
at org.apache.naming.NamingContext.rebind(NamingContext.java:225)
It seems like the container can't found context base on AppServer.
I am not a master of JNDI. Then I have checked some documents. The java:comp/env/ is the basic namespace. And "jdbc" for DBCTM DataSource references, "jms" for JMS connection factories, "mail" for JavaMail connection factories, "url" for URL connection factories.
We don't want to change too much on our old application code. It's not use any special features of Glassfish. I want to know how to define a JNDI in a correct way.
Is there anyone could tell me why Glassfish can use AppServer as namespace, but TomEE can't.
Tomcat (then TomEE) is not designed to change JNDI at runtime like it. Saying it simply the best is to not use this pattern but a contextual resource. Inject the resource you desire and that's this resource you change instead of JNDI (which is quite more impacting that it seems)
I am porting a suite of related applications from WebLogic to JBoss EAP v6.2.
I have set up a data source connection using the JBoss command line interface and hooked it to an oracle database. This database has a name of "mydatasource" and a JNDI name of
"java:jboss/datasources/mydatasource" as per JBoss standards. I can test and validate this database connection.
However, when I try to port the code and run it, the connection doesn't work. The code that worked in WebLogic was simply:
InitialContext ic = new InitialContext() ;
DataSource ds = (DataSource)ic.lookup(dataSource) ;
with a value in dataSource of "mydatasource".
This worked in Web Logic but in JBoss it throws a NameNotFoundException
javax.naming.NameNotFoundException: mydatasource-- service jboss.naming.context.java.mydatasource
Clearly there is a difference in how the InitialContext is set up between the two servers.
But this port involves a large number of small applications, all of which connect to the datasource via code like that above. I don't want to rewrite all that code.
Is there a way through configuration (InitialContextFactory, maybe) to define the initial context such that code like that above will work without rewriting, or perhaps is there another way of naming the datasource that JBoss will accept that would allow code like that above to work without rewriting?
Or must we bite the bullet and accept that this code needs a rewrite?
Update: Yes, I know that simply passing "java:jboss/datasources/mydatasource" to the InitialContext lookup solves the problem, but I am looking for a solution via configuration, rather than via coding if there is such a solution.
The way to do this correctly through configuration is to use
java:comp/env/jdbc/myDataSource
then use resource-ref in web.xml to map it to the declare datasource and use weblogic.xml or jboss-web.xml to actually map it to the real one
in weblogic admin console, when you define datasource it can be jdbc/realDataSource
JNDI path Tomcat vs. Jboss
For weblogic http://docs.oracle.com/cd/E13222_01/wls/docs103/jdbc_admin/packagedjdbc.html
I'm running Jackrabbit 2.6.4 in Glassfish 4. I have deployed Jackrabbit as a connector resource using the provided rar.
I have got it up and running so that I can call the Jackrabbit repository from inside stateless EJB's and can create nodes etc.. I am now trying to replace the Default LoginModule Mechanism that is provided out of the box with my own custom LoginModule.
So far I have:
Created a Custom Realm and LoginModule that returns a users Principles (currently String values e.g. admin, read, write) and deployed this to the domain/lib directory
Configured my web.xml and sun-web.xml files with the roles to group mappings and enabled basic authentication. This is all working as expected and I can enforce roles on my EJBs.
Got Jackrabbit to use my Custom Login module instead of it's own (I removed the login module configuration from repository.xml and changed the security app name to match my realm name)
I am now running into the following problems:
Jackrabbit does not find the existing subject created by the application container when I login. This appears to be a problem with the way Jackrabbit looks up the Subject:
AccessControlContext acc = AccessController.getContext();
subject = Subject.getSubject(acc);
This returns null in Glassfish. Instead it appears you need to use:
Subject subject = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
I worked round this issue by getting the subject using the above code and then logging in to a repository inside a Subject.doAs block e.g.
Subject.doAs(subject, new PrivilegedAction<String>() {
#Override public String run() {
Session session = null;
try {
session = repository.login();
} catch (RepositoryException e) {
log.error("Failed", e);
} finally {
if (session != null) {
session.logout();
}
}
This now works but the next problem is that the JackRabbit DefaultAccessManager expects the Subject to contain JackRabbit typed principles e.g. org.apache.jackrabbit.core.security.SystemPrincipal which I can not return from my custom login module as it does not have access to the JackRabbit classes.
My first attempt to work around this was to create my own AccessManager but JackRabbit can't instantiate this as it is in my WAR and is not available to the JackRabbit code inside the connector resource.
My next attempt was to programmatically add the principle to the Subject inside my EJB before passing it to Jackrabbit, this worked but then I discovered running Subject.doAs inside an EJB in glassfish causes a number of issues and does not appear to be supported. There are also background threads inside Jackrabbit that need a subject with the JackRabbit typed principles in it.
I am now completely stumped on how to get a custom JAAS glassfish login module to work with Jackrabbit inside Glassfish and am wondering if anyone out there has figured this out.
In the mean time I am currently considering giving up on JackRabbit security and handling it all in my application layer and just using the default login module under the covers to log into Jackrabbit.
I've finally got Glassfish, JackRabbit and JAAS working together so that I can create a Subject using my custom LoginModule that JackRabbit then uses to create a session. Below are the steps that I took to resolve this issues described in my original question:
Instead of using the JackRabbit RAR (Model 2) I now include the JackRabbit Jars inside my war (Model 1). This allowed me to implement my own custom AccessManager that does not rely on the JackRabbit typed principles. The biggest disadvantage of this approach is that I now have to create and shutdown the repository myself. The solution I went with was an ApplicationScoped CDI Producer that creates the repo and the shuts it down in the dispose method. This makes it easy to inject the repo into the classes.
I solved the issue with JackRabbit finding the Subject in Glassfish by patching jackrabbit-core. It appears this issue has been around for some time see (JCR-3188), and a patch has been provided but never included in the source code. I applied the patch to 2.6.4 and JackRabbit is now able to find and use the Subject in Glassfish.
I'm troubleshooting a Mapper problem and I'm running into an issue trying to use a Mapper class inside of the Scala/Lift console. Our MetaMappers have their datasource configured through a ConnectionIdentifier that points to a JDBC datasource configured in JNDI. This works great when bootstrapping through Jetty.
When loading the console and running (new bootstrap.liftweb.Boot).boot to initialize, Schemifier.schemify fails JNDI configuration is not available.
scala> (new bootstrap.liftweb.Boot).boot
java.lang.NullPointerException: Looking for Connection Identifier ConnectionIdentifier(jdbc/svcHub) but failed to find either a JNDI data source with the name jdbc/svcHub or a lift connection manager with the correct name
at net.liftweb.mapper.DB$$anonfun$7$$anonfun$apply$12.apply(DB.scala:141)
at net.liftweb.mapper.DB$$anonfun$7$$anonfun$apply$12.apply(DB.scala:141)
at net.liftweb.common.EmptyBox.openOr(Box.scala:465)
at net.liftweb.mapper.DB$$anonfun$7.apply(DB.scala:140)
at net.liftweb.mapper.DB$$anonfun$7.apply(DB.scala:140)
at net.liftweb.common.EmptyBox.openOr(Box.scala:465)
at net.liftweb.mapper.DB$.newConnection(DB.scala:134)
at net.liftweb.mapper.DB$.getConnection(DB.scala:230)
at net.liftweb.mapper.DB$.use(DB.scala:581)
at net.liftweb.mapper.Schemifier$.schemify(Sche...
Essentially, I'd like to have full MetaMapper functionality from within the console. My question is: What's the best way to bootstrap a Lift app from the console such that the JNDI-based dependencies can also be fulfilled outside of a JNDI-capable web container?
Under a application server it's likely that the server will provide a JNDI context for you. In a standalone application you must provide a JNDI Context your self. For that you can use a javax.naming.InitialContext.
There is a nice example using Apache's DBCP here: http://commons.apache.org/dbcp/guide/jndi-howto.html. Of course, will you have to fix the Datasource objects to the implementation you are using.
This will be enough (not very elegant, though) for simple JNDI usage.