I am facing problem as the actual imported java file is not being called. Please have a look of my code :-
import javax.naming.Context;
import javax.naming.InitialContext;
.....
public class ABC{
.....
1. Context lContext = null;
2. ObjectDataSourceFactory lSource = null;
3. try
4. {
5. lContext = new InitialContext();
6. lSource = ((ObjectDataSourceFactory)lContext.lookup(....));
}
catch (Exception e)
{
}
The Problem I am facing here is : when flow control goes into line number 6. it calls the "lookup method" from "SelectorContext.java" but not from "InitialContext.java", I have found this with the help of DEBUGGING mode in eclipse . As a result it cannot find the proper JNDI and gives exception.
FYI..
My code is running on Tomcat6.
I have set the classpath of jar files from my JRE1.6 and so the JDK.
Can someone please suggest me -
how can I know from which JAR this "SelectorContext.java" is being called and how to make it to Look into the InitialContext.class which is present inside RT.JAR, if I am not wrong ?
Your understanding is not correct. SelectorContext is one of the JNDI implementations of the tomcat.
There is an option to use external JNDI context by setting java.naming.factory.initial as system variable. This is set by Tomcat (javaURLContextFactory) to provide it's own JNDI services.
When you call new InitialContext(), JVM sees if there is user provided naming factory, and if it is available, JVM calls initialFactory.getInitialContext to get the custom JNDI implementation and makes this default and all the method calls to context is inturn routed to custom implementation.
In your case, call to SelectorContext is right, see if you have the required configuration in place to have the resource in JNDI.
Related
I'm trying to connect to EJB on WebSphere 7.0. The EJB requires javax.ejb.SessionContext and reads Principal from it, so I need to log in before calling it.
I'm using the following code in stand-alone application:
import javax.naming.InitialContext;
import javax.security.auth.login.LoginContext;
import com.ibm.websphere.security.auth.WSSubject;
import com.ibm.websphere.security.auth.callback.WSCallbackHandlerImpl;
public static void main(String[] args) throws Exception {
InitialContext ic = new InitialContext(System.getProperties());
LoginContext lc = new LoginContext("WSLogin",
new WSCallbackHandlerImpl("myuser","mypass"));
lc.login();
WSSubject.setRunAsSubject(lc.getSubject());
SessionContext sessionContext=(SessionContext) ic.lookup(
"java:comp/env/sessionContext");
}
I've added the entry to my jmxremote.access:
myuser readwrite
However, I get an exception:
Caused by: javax.naming.ConfigurationException: Name space accessor
for the java: name space has not been set. Possible cause is that the
user is specifying a java: URL name in a JNDI Context method call but
is not running in a J2EE client or server environment. at
com.ibm.ws.naming.java.javaURLContextFactory.isNameSpaceAccessable(javaURLContextFactory.java:98)
at
com.ibm.ws.naming.urlbase.UrlContextFactory.getObjectInstance(UrlContextFactory.java:82)
at
javax.naming.spi.NamingManager.getURLObject(NamingManager.java:584)
at
javax.naming.spi.NamingManager.getURLContext(NamingManager.java:533)
at
javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:320)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
What else should I do, to run my code in the 'J2EE client environment' mentionend in the error message?
In order to use java:comp, you would need to package the client application in an .ear and use launchClient. Ultimately, that's just going to use -CCBootstrapHost/-CCBootstrapPort (or defaults) to connect to the target server to look up the EJB, so you could just use the EJB thinclient and use the fully-qualified EJB binding name instead (see the CNTR0167I messages in SystemOut.log).
you'll need to use the WAS client runtime JARs. WAS_HOME/AppServer/runtimes. You will need the ORB and the other service specific JARs. As an alternative to using launchClient, you can manually specify the context factory you'll be using here:
InitialContext ic = new InitialContext(System.getProperties());
set the
java.naming.factory.initial
variable (in your system env or in a Properties object) to
com.ibm.websphere.naming.WsnInitialContextFactory`
Using GlassFish 3.1.2, I try to call a Session Bean from a Netbeans platform module, and I get a null pointer exception. My problem is that I have no trace explaining how / where the NPE is generated.
The code in my Module is simply:
import ejb.MySessionRemote;
import javax.ejb.EJB;
public class TestServer {
#EJB
private static MySessionRemote mySession;
public boolean execute() {
System.out.println("result = " + mySession.getString()); //NPE here: mySession is null
return true;
}
}
The Session bean "My Session", the remote interface and the application deployed on the server side are just the ones from this tutorial: https://netbeans.org/kb/docs/javaee/entappclient.html
Any help greatly appreciated.
Note: I've checked this tutorial, without solving my issue.
If mySession is null, it was probably not injected. You can inject into managed beans (EJBs for example), because these instances are managed (created/removed) by a container, and the container does the injection for you.
You can possibly inject into a POJO, if you use CDI.
If TestServer is part of a stand-alone application for example, try to lookup the EJB using JNDI. This is what your tutorial does as well. It involves setting up the properties to get an InitialContext, and the lookup of the EJB using JNDI.
Note that I'm mirroring the example given here very closely.
In fact, my situation is somewhat simpler as I'm not even testing with a persistence unit at this point. My test project provides a simple MDB and a session bean; both the MDB and the session bean are getting loaded as normal, and can be successfully tested (in a constrained fashion) without injection.
The suggested injection with the #LocalClient annotation on my unit tests is failing with the known error:
javax.naming.NamingException: Unable to find injection meta-data for [your-class]. Ensure that class was annotated with #org.apache.openejb.api.LocalClient and was successfully discovered and deployed. See http://openejb.apache.org/3.0/local-client-injection.html
When I visit this page it informs me that I may need to add an extra property to my test case context setup. So that now looks like:
#Override
public void setUp() throws Exception {
initializeContext();
}
public void initializeContext() {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory");
// the property i've added
p.put("openejb.tempclassloader.skip", "annotations");
try {
InitialContext initialContext = new InitialContext(p);
initialContext.bind("inject", this);
} catch (Throwable throwable) {
throwable.printStackTrace();
throw new RuntimeException(throwable);
}
}
But it's still failing. I really like this idiom and would be very excited if I could successfully use it in my projects.
A few other notes:
I am providing an 'empty' ejb-jar.xml (in src/main/resources) and an application-client.xml (in src/test/resources) as suggested by Apache to tell OpenEJB to scan the classpath [UPDATE: as it turns out, I was doing this wrong. See my answer below for the suggestion that worked for me.]
The test cases annotated with #LocalClient aren't identified by the OpenEJB engine as actually getting picked up and processed properly (as my MDBs are, for example)
Thanks in advance for any help or guidance.
This issue is likely caused by improper location of the descriptors which hint OpenEJB which sorts of modules are available.
To ensure the test-classes get picked up properly, make sure you're placing a file named application-client.xml at src/test/resources/META-INF with the following content:
<application-client/>
This should force OpenEJB to scan and react to the presence of #LocalClient annotations.
I had a similar issue when I tried to test stuff in a test project called tomee-embedded-trial and it turned out that openejb ignores stuff called tomee-.* .
I fixed it for me by specifying the following system properties:
openejb.deployments.classpath.include=".*-trial.*" openejb.deployments.package.include=".*-trial.*"
I've been trying to get a sample JMX MXBean working in a Spring-configured webapp, but any basic attributes on the MXBean are coming up as UNDEFINED when I connect with jconsole.
Java interface/classes:
public interface IJmxBean { // marker interface for spring config, see below
}
public interface MgmtMXBean { // lexical convention for MXBeans - mgmt interface
public int getAttribute();
}
public class Mgmt implements IJmxBean, MgmtMXBean { // actual JMX bean
private IServiceBean serviceBean; // service bean injected by Spring
private int attribute = 0;
#Override
public int getAttribute() {
if(serviceBean != null) {
attribute = serviceBean.getRequestedAttribute();
}
return attribute;
}
public void setServiceBean(IServiceBean serviceBean) {
this.serviceBean = serviceBean;
}
}
Spring JMX config:
<beans>
<context:component-scan base-package="...">
<context:include-filter type="assignable" expression="...IJmxBean" />
</context:component-scan>
<context:mbean-export />
</beans>
Here's what I know so far:
The element is correctly instantiating a bean named "mgmt". I've got logging in a zero-argument public constructor that indicates it gets constructed.
is correctly automatically detecting and registering the MgmtMXBean interface with my Tomcat 6.0 container. I can connect to the MBeanServer in Tomcat with jconsole and drill down to the Mgmt MXBean.
When examining the MXBean, "Attribute" is always listed as UNDEFINED, but jconsole can tell the correct type of the attribute. Further, hitting "Refresh" in jconsole does not actually invoke the getter method of "Attribute"- I have logging in the getter method to indicate if it is being invoked (similar to the constructor logging that works) and I see nothing in the logs.
At this point I'm not sure what I'm doing wrong. I've tried a number of things, including constructing an explicit Spring MBeanExporter instance and registering the MXBean by hand, but it either results in the MBean/MXBean not getting registered with Tomcat's MBean server or an Attribute value of UNDEFINED.
For various reasons, I'd prefer not to have to use Spring's #ManagedResource/#ManagedAttribute annotations.
Is there something that I'm missing in the Spring docs or MBean/MXBean specs?
ISSUE RESOLVED: Thanks to prompting by Jon Stevens (above), I went back and re-examined my code and Spring configuration files:
Throwing an exception in the getAttribute() method is a sure way to get "Unavailable" to show up as the attribute's value in JConsole. In my case:
The Spring JMX config file I was using was lacking the default-autowire="" attribute on the root <beans> element;
The code presented above checks to see if serviceBean != null. Apparently I write better code on stackoverflow.com than in my test code, since my test code wasn't checking for that. Nor did I have implements InitializingBean or #PostConstruct to check for serviceBean != null like I normally do on almost all the other beans I use;
The code invoking the service bean was before the logging, so I never saw any log messages about getter methods being entered;
JConsole doesn't report when attribute methods throw exceptions;
The NPE did not show up in the Tomcat logs.
Once I resolved the issue with serviceBean == null, everything worked perfectly. Regardless, +1 to Jon for providing a working demo, since there are literally 50 different ways to configure MBeans/MXBeans within Spring.
I've recently built a sample Spring based webapp that very cleanly enables JMX for latest versions of Spring, Hibernate and Ehcache.
It has examples for both EntityManager based access and DAO access (including transactions!). It also shows how to do annotation based injection in order to negate having to use Spring's xml config for beans. There is even a SpringMVC based example servlet using annotations. Basically, this is a Spring based version of a fairly powerful application server running on top of any servlet engine.
It isn't documented yet, but I'll get to that soon. Take a look at the configuration files and source code and it should be pretty clear.
The motivation behind this is that I got tired of all of the crazy blog posts with 50 different ways to set things up and finally made a single simple source that people can work from. It is up on github so feel free to fork the project and do whatever you want with it.
https://github.com/lookfirst/fallback
I am attempting to use JNDI with a custom DataSource called CEDataSource. From my understanding for this to work I would have to create a custom factory as well.
So I created a custom factory that would return the CEDataSource object but now when I attempt to use this in Java with
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
// Look up our data source
CEDataSource ds = (CEDataSource)envCtx.lookup("jdbc/cePu");
I get the exception ClassCastException
"CEDataSource cannot be mapped to CEDataSource". I added the CEDataSource and the CEDataSourceFactory to the TOMCAT/lib folder as well as referenced this same jar on my deployed application.
Any help would be greatly appreciated on why this possible error may occur. Thanks
"CEDataSource cannot be mapped to CEDataSource" seems to point to the fact that it's not the same "CEDataSource" in both places.
What could be different is the classloader and this usually happens if you have the same jars/.class(es) in multiple locations.
Do you have multiple copies of your jar?
Try to have a single copy, maybe in the shared tomcat lib so it's loaded by the same classloader no matter from where you access it from.
It is actually not too difficult to start Tomcat under an Eclipse debug session (just put all the Bootstrap.jar in a project and add the System properties in the JVM parameters). II've done that many times, if only to dissect the bowels of that feline. Once this is done you can break on the class cast exception of the JNDI connection factory and you will then be able to see if your factory is called or not.
From what I remember Tomcat uses the DBCP DataSource. Actually repackaged under com.apache.tomcat.dbcp.dbcp.DataSource (IIRC).
So I would not be surprised if this is what you end up with as a result of your look-up.
With hindsight, I now realize I also forgot to mention that if any underlying class (for instance a JDBC driver) needed to create the instance of your CEDataSource is missing you also get this ClassCastException. Fair enough, but you always focus on the class itself and not on the other jars...
CEDataSource ds = (CEDataSource)envCtx.lookup("jdbc/cePu");
The lookup you are doing on jdbc/cePu is not of class type CEDataSource , it belongs to some other class type, that is why you are getting class cast exception. if you could show me the configuration for jdbc/cePu that would be helpful.