Is is possible to create JNDI llookup and it's reference in standalone application means without any application server.
java:comp/env/jdbc
Regards,
Chaitu
JNDI is a service which is provided by Java platform. Refer to below link
http://www.javaworld.com/javaworld/jw-04-2002/jw-0419-jndi.html
You can use the class org.springframework.mock.jndi.SimpleNamingContextBuilder of Spring, either the dependency or the file spring-mock-1.0.2.jar. e.g.:
Setup:
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
builder.bind("jdbc/Oracle", ods);
builder.activate();
Use:
DataSource ds = InitialContext.doLookup("jdbc/Oracle");
I found a better solution courtesy of Injecting JNDI datasources
(https://web.archive.org/web/20140530014804/https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit)
NEW SOLUTION
How to Run JUnit Tests that require "java:/comp/env/jdbc/keyofsomethingegdatabase"
Add the following Jar's to the JUnit test-case's CLASSPATH:
TOMCAT_HOME/bin/tomcat-juli.jar (required by catalina.jar)
TOMCAT_HOME/lib/catalina.jar (contains the actual factory)
Create the binding that you require in the static "for-all-tests" method:
#BeforeClass
public static void setUpClass() throws Exception {
...
// Use Apache Tomcat's Directory
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
// Standard hook
InitialContext initialContext = new InitialContext();
// Create binding
initialContext.createSubcontext("java:");
initialContext.createSubcontext("java:comp");
initialContext.createSubcontext("java:comp/env");
initialContext.createSubcontext("java:comp/env/jdbc");
// Construct DataSource
OracleConnectionPoolDataSource dataSource = new OracleConnectionPoolDataSource();
dataSource.setURL("jdbc:oracle:thin:#myserver:1521:MYSID");
dataSource.setUser("username");
dataSource.setPassword("password");
initialContext.bind("java:comp/env/jdbc/mydatabase", dataSource);
...
}
Then you can create this method in your Singleton class (either lookup method works):
public Connection getConnection() throws NamingException, SQLException {
if (dataSource == null) {
Context initialContext = new InitialContext();
boolean bLooksLikeChangeDirectory = false;
if (bLooksLikeChangeDirectory) {
Context context = (Context) initialContext.lookup("java:comp/env");
dataSource = (DataSource) context.lookup("jdbc/mydatabase");
} else {
dataSource = (DataSource) initialContext.lookup("java:comp/env/jdbc/mydatabase");
}
}
Connection result = dataSource.getConnection();
return result;
}
OLD SOLUTION FOLLOWS
This is how you can use a stand-alone JNDI (file-based) for running tests involving: "new InitialContext() ... "lookup".
This also describes how to use BoneCP (Connection Pool) with JNDI.
You can use the "com.sun.jndi.fscontext.RefFSContextFactory" (fscontext.jar and providerutil.jar).
I wanted "lookup" to be runnable from inside an application server as well, so it would be useful if someone could tell me for sure if one has to use lookup("java:comp/env/jdbc/mydbnickname") instead of lookup("jdbc/mydbnickname") when running inside an application server.
The latter is preferable, because "java:comp/env" does not exist in the stand-alone RefFSContextFactory directory, so you'd have to have a System property that specifies the JNDI lookup parameter.
Overview
You can use "jdbc/mydbnickname" as the argument to "lookup" and to "rebind" (i.e. no "scheme:").
In this case, "RefFSContextFactory" uses the "default scheme", whatever that is ("file:" or "jndi:").
With the following in "jndi.properties" (on the CLASSPATH)
java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory
java.naming.provider.url=file:///u:/workdirectory
and this in "persistence.xml" (JTA setup)
<jta-data-source>jdbc/mydbnickname</jta-data-source>
When you use:
...rebind("jdbc/mydbnickname", ...)
and
...lookup("jdbc/mydbnickname")
then the ".bindings" file (created by "rebind") is
"u:/workdirectory/.bindings"
and it looks like this (I have sorted it and tested it with just "lookup"):
#This file is used by the JNDI FSContext.
#Thu Jan 09 16:02:17 EST 2014
jdbc/mydbnickname/ClassName=com.jolbox.bonecp.BoneCPDataSource
jdbc/mydbnickname/FactoryName=com.jolbox.bonecp.BoneCPDataSource
jdbc/mydbnickname/RefAddr/0/Content=oracle.jdbc.OracleDriver
jdbc/mydbnickname/RefAddr/0/Encoding=String
jdbc/mydbnickname/RefAddr/0/Type=driverClassName
jdbc/mydbnickname/RefAddr/1/Content=jdbc\:oracle\:thin\:#myserver\:1521\:mysid
jdbc/mydbnickname/RefAddr/1/Encoding=String
jdbc/mydbnickname/RefAddr/1/Type=jdbcUrl
jdbc/mydbnickname/RefAddr/2/Content=myusername
jdbc/mydbnickname/RefAddr/2/Encoding=String
jdbc/mydbnickname/RefAddr/2/Type=username
jdbc/mydbnickname/RefAddr/3/Content=mypassword
jdbc/mydbnickname/RefAddr/3/Encoding=String
jdbc/mydbnickname/RefAddr/3/Type=password
If you use
"jndi:jdbc/mydbnickname"
instead of
"jdbc/mydbnickname",
then the file created is
u:/workdirectory/jdbc/.bindings
and it looks like this:
mydbnickname/ClassName=com.jolbox.bonecp.BoneCPDataSource
mydbnickname/FactoryName=com.jolbox.bonecp.BoneCPDataSource
mydbnickname/RefAddr/0/Content=oracle.jdbc.OracleDriver
mydbnickname/RefAddr/0/Encoding=String
mydbnickname/RefAddr/0/Type=driverClassName
mydbnickname/RefAddr/1/Content=jdbc\:oracle\:thin\:#myserver\:1521\:mysid
mydbnickname/RefAddr/1/Encoding=String
mydbnickname/RefAddr/1/Type=jdbcUrl
mydbnickname/RefAddr/2/Content=myusername
mydbnickname/RefAddr/2/Encoding=String
mydbnickname/RefAddr/2/Type=username
mydbnickname/RefAddr/3/Content=mypassword
mydbnickname/RefAddr/3/Encoding=String
mydbnickname/RefAddr/3/Type=password
Rebind (in a JUnit Test)
#BeforeClass
public static void setUpClass() throws Throwable {
final String sMyName = "setUpClass";
try {
if (Boolean.parseBoolean(System.getProperty("test.initialcontext.rebind", "true"))) {
final InitialContext initialContext = new InitialContext();
final String contextName = "jdbc/mydbnickname";
final Reference contextValue = new Reference("com.jolbox.bonecp.BoneCPDataSource", "com.jolbox.bonecp.BoneCPDataSource", null);
contextValue.add(new StringRefAddr("driverClassName", "oracle.jdbc.OracleDriver"));
contextValue.add(new StringRefAddr("jdbcUrl", "jdbc:oracle:thin:#myserver:1521:mysid"));
contextValue.add(new StringRefAddr("username", "myusername"));
contextValue.add(new StringRefAddr("password", "mypassword"));
initialContext.rebind(contextName, contextValue);
}
} catch (final Throwable exception) {
Utils.getInstance().logExceptionStack(logger, Level.ERROR, sMyName, exception);
throw exception;
}
}
Lookup (in production code)
protected Connection getConnection() throws Exception {
Connection result = null;
// "An InitialContext instance is not synchronized against concurrent access by multiple threads"
synchronized (this) {
if (context == null) {
context = new InitialContext();
}
final BoneCPDataSource connectionPool = (BoneCPDataSource) context.lookup("jdbc/mydbnickname");
result = connectionPool.getConnection();
}
return result;
}
CLASSPATH
BoneCP Connection Pool
<classpathentry kind="var" path="JAVA_LIB/bonecp-0.8.0.RELEASE.jar" sourcepath="/JAVA_LIB/bonecp-0.8.0.RELEASE-sources.jar"/>
<classpathentry kind="var" path="JAVA_LIB/slf4j-api-1.7.5.jar" sourcepath="/JAVA_LIB/slf4j-api-1.7.5-sources.jar"/>
<classpathentry kind="var" path="JAVA_LIB/guava-15.0.jar" sourcepath="/JAVA_LIB/guava-15.0-sources.jar"/>
<classpathentry kind="var" path="JAVA_LIB/slf4j-simple-1.7.5.jar" sourcepath="/JAVA_LIB/slf4j-simple-1.7.5-sources.jar"/>
Eclipse JPA (2.5.1)
<classpathentry kind="var" path="JAVA_LIB/javax.persistence-2.1.0.jar"/>
<classpathentry kind="var" path="JAVA_LIB/eclipselink-2.5.1.jar"/>
JNDI
<classpathentry kind="var" path="JAVA_LIB/fscontext.jar"/>
<classpathentry kind="var" path="JAVA_LIB/providerutil.jar"/>
Related
I build webApp . When I run app from Eclipse everything work OK. Now I build WAR file, put in tomcat root, andI want to all my system property put in context.xml in tomcat. Then, when app is start, that values from context.xml is read and use in app.
Problem is I don't know how to get values from context.xml in my webapp?
This is context:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="" docBase="fileupload.war" privileged="true" antiResourceLocking="false" antiJARLocking="false">
<Resource
mail.smtp_server = "127.0.0.1"
mail.smtp_username = "no-reply#gmail.rs"
mail.mailTo = "test#gmail.com"
rootFolder = "D:/project/"
rootFolderBackup = "D:/project/Backup/"
/>
Here I want to get a values from context.xml :
#RequestMapping(value="api/files")
public class FileController {
final static Logger logger = Logger.getLogger(FileController.class);
#Autowired
ApplicationContext applicationContext;
private String mailTo;
private String sender;
private String rootFolder = "";
private String rootFolderBackup = "";
#PostConstruct
private void init(){
try {
InitialContext ic = new InitialContext();
Context xmlContext = (Context) ic.lookup("java:comp/env"); // thats everything from the context.xml and from the global configuration
DataSource myDatasource = (DataSource) xmlContext.lookup("rootFolder");
} catch (NamingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
This is common error :
Name [rootFolder] is not bound in this Context. Unable to find [rootFolder].
I try few solution which I found on web but not working...
My context.xml file is in C:\tomcat-7.0\conf\Catalina\localhost , and war file is in C:\tomcat-7.0\webapps
If you want to define application properties you should probably use Environment variables instead. Ex you can set a variable in any context.xml like this:
<Environment name="PROPERTIES_FILE" override="false" type="java.lang.String" value="C:/path/to/propfile.properties" />
<!--define more variables here -->
and then in your application you can read those environment properties from JNDI like this.
initCtx = new InitialContext();
String path = (String) initCtx.lookup("java:comp/env/PROPERTIES_FILE");
// fetch more variables here
Further reading:
https://tomcat.apache.org/tomcat-8.0-doc/config/context.html#Environment_Entries
https://tomcat.apache.org/tomcat-8.0-doc/jndi-resources-howto.html
I have an application that i use for buiding reports, now I need to move this application to Web environment.
For that I am using Tomcat 8.0.15 and an Oracle Database 11g Enterprise Edition.
In my TOMCAT_HOME\conf\server.xml i have the following code:
<Resource auth="Container"
driverClassName="oracle.jdbc.OracleDriver"
maxIdle="10"
maxTotal="20"
maxWaitMillis="-1"
name="jdbc/reportDataSource"
username="some_username"
password="some_pass"
type="javax.sql.DataSource"
url="jdbc:oracle:thin:#(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = some.host)(PORT = some.port)))(CONNECT_DATA =(SID = SOME_SID)(SERVICE_NAME = SOME_SERVICE)))"/>
Therefore in my PROJECT_HOME\WebContent\WEB-INF\web.xml I have the following:
<resource-ref>
<description>Oracle Datasource definition</description>
<res-ref-name>jdbc/reportDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Finally in my code I have a Java class with the following:
private void init() throws NamingException, SQLException {
try {
InitialContext initialContext = new InitialContext(); // JNDI initial context
Context eventContext = (Context) initialContext.lookup("java:comp/env/jdbc/reportDataSource"); // Event context
dataSource = (DataSource) eventContext.lookup("jdbc/reportDataSource"); // JNDI lookup
databaseConnection = dataSource.getConnection(); // database connection through data source
} catch (SQLException se) {
throw new SQLException("Connection object was not created. Rejected by host or not found.");
} catch (NamingException ne) {
throw new NamingException(ne.getMessage());
}
}
Finally in my project root I have have the following test setup:
#Before
public void setUp() throws Exception {
dbConnectorManager = new DatabaseConnectorManager();
assertNotNull(dbConnectorManager);
}
When I call the DatabaseConnectorManager() it calls the init() method shown in this question. However when I execute my test I got the following error related with line:
entContext eventContext = (Context) initialContext.lookup("java:comp/env/jdbc/reportDataSource"); // Event context
Hence, it is not possible to setup JNDI due the following error:
javax.naming.NamingException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
Can you please advise if I can create these JUnit tests for testing the connectivity, or if I can only test through a servlet?
Is there anything wrong with my configuration?
Update
I made the desiganted changes but now I get the following error:
javax.naming.NamingException: Name [jdbc/reportDataSource] is not bound in this Context. Unable to find [jdbc].
My data source now looks like the following:
InitialContext initialContext = new InitialContext(); // JNDI initial context
Context eventContext = (Context) initialContext.lookup("java:comp/env"); // Event context
dataSource = (DataSource) eventContext.lookup("jdbc/reportDataSource"); // JNDI lookup
databaseConnection = dataSource.getConnection(); // database connection through data source
'not sure this is the error, but you probably have a typo here:
Context eventContext =
(Context) initialContext.lookup("java:comp/env/jdbc/reportDataSource"); // Event context
// ^^^^^^^^^^^^^^^^^^^^^^
dataSource = (DataSource) eventContext.lookup("jdbc/reportDataSource"); // JNDI lookup
// ^^^^^^^^^^^^^^^^^^^^^^
Either you want to do a direct lookup:
dataSource =
(DataSource) initialContext.lookup("java:comp/env/jdbc/reportDataSource");
Or you want to get the context first, but in that case, you only requests java:comp/env:
Context eventContext =
(Context) initialContext.lookup("java:comp/env");
dataSource = (DataSource) eventContext.lookup("jdbc/reportDataSource");
In Server.xml, provide a name to your resource and do the lookup based on that name. Another point is, you can add a resource as a new context.xml under META-INF folder under webapps. This is done if you don't want to change your server.xml
<Resource name="tomcat/JDBCdatasource" auth="Container" ... />
Context ctx;
ctx = new InitialContext();
Context envContext = (Context) ctx.lookup("java:/comp/env");
// Look up a data source
javax.sql.DataSource ds
= (javax.sql.DataSource) envContext.lookup ("tomcat/JDBCdatasource");
I am learning Spring MVC. I am trying to use #Resource to inject DataSource. It is like this:
web.xml of Tomcat:
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
context.xml:
Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="sa" password="" driverClassName="org.h2.Driver"
url="jdbc:h2:tcp://localhost/~/test"/>
The controller code (using Spring MVC framework):
#Controller
public class SimpleControllerAnnotation {
//#Resource(name="dataSource")
#Resource(name="jdbc/TestDB")
private DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
//#Resource(name="dataSource")
#Resource(name="jdbc/TestDB")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
#RequestMapping("/testDataSource")
public ModelAndView testDataSource() {
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
String name = null;
String ID = null;
try {
con = dataSource.getConnection();
stmt = con.createStatement();
rs = stmt.executeQuery("select ID, name from STUDENT");
while(rs.next()){
name = rs.getString("name");
ID = rs.getString("ID");
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
if(rs != null) rs.close();
if(stmt != null) stmt.close();
if(con != null) con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
ModelAndView mw = new ModelAndView("TestDataSourceForm");
mw.addObject("DataSourceValue",dataSource);
mw.addObject("Name",name);
mw.addObject("ID",ID);
return mw;
}
In this code, I am using #Resource to inject the DataSource, which I intend to "get" from Tomcat, which I set up in Tomcat (the web.xml and context.xml shared above).
When I run this program, I get the following exception:
SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'simpleControllerAnnotation': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'jdbc/TestDB' is defined
The jdbc/TestDB is the DataSource which I set up in Tomcat.
I have following queries:
1) Is it possible to have DataSource which we create in Tomcat to be injected this way? Or we have to use JNDI lookup. In one of the posts that I read on internet, it was said that JNDI lookup is sort of outdated and these days Dependency injection is preferred way.
2) In general, is it best practice to set-up the DataSources in App server/Web Container or to manage in the application itself. From what I read over the posts, it is preferred let App server/Container to manage this.
Any help to past this error really appreciated.
Apache Tomcat processes #Resource annotations only on classes that it itself loads (such as Filters, Servlets and Listeners).
In your case your controller class is loaded by Spring Framework and Spring is responsible for processing the #Resource annotation. Read the Spring documentation (Reference guide).
According to Spring Reference Guide [1], the value in #Resource annotation is the name of a Spring bean.
It says that the name can be used for JDNI lookup if you configure a SimpleJndiBeanFactory, but recommends against it and advices to configure referenced beans explicitly. -> [2]
[1] http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-resource-annotation
[2] http://docs.spring.io/spring/docs/current/spring-framework-reference/html/xsd-config.html#xsd-config-body-schemas-jee
I have installed Websphere Network deployment server 7.0.0.0
I have configured a cluster on it.
I have configured a data source on it say ORA_DS this data source using "JAAS - J2C authentication data"
When i test the ORA_DS by clicking on "Test connection" button, the test connection is success.
The issue comes when i try to access this data source using my java code.
Here is my code to access data source and create a connection:
public class DSTester
{
/**
* Return the data source.
* #return the data source
*/
private DataSource getDataSource()
{
DataSource dataSource = null;
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
env.put(Context.PROVIDER_URL, "iiop://localhost:9811");
// Retrieve datasource name
String dataSourceName = "EPLA1";
if (dataSource == null)
{
try
{
Context initialContext = new InitialContext(env);
dataSource = (DataSource) initialContext.lookup(dataSourceName);
}
catch (NamingException e1)
{
e1.printStackTrace();
return null;
}
}
return dataSource;
}
public static void main(String[] args)
throws Exception
{
DSTester dsTester = new DSTester();
DataSource ds = dsTester.getDataSource();
System.out.println(ds);
System.out.println(ds.getConnection());
}
}
Here is the output:
com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource#17e40be6
Exception in thread "P=792041:O=0:CT" java.sql.SQLException: ORA-01017: invalid username/password; logon denied
DSRA0010E: SQL State = 72000, Error Code = 1,017
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:206)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:455)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:406)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
at oracle.jdbc.driver.T4CTTIoauthenticate.receiveOauth(T4CTTIoauthenticate.java:799)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:368)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:508)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:203)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:33)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:510)
at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:275)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:206)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPhysicalConnection(OracleConnectionPoolDataSource.java:139)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:88)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:70)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper$1.run(InternalGenericDataStoreHelper.java:1175)
at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper.getPooledConnection(InternalGenericDataStoreHelper.java:1212)
at com.ibm.ws.rsadapter.spi.WSRdbDataSource.getPooledConnection(WSRdbDataSource.java:2019)
at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.createManagedConnection(WSManagedConnectionFactoryImpl.java:1422)
at com.ibm.ws.rsadapter.spi.WSDefaultConnectionManagerImpl.allocateConnection(WSDefaultConnectionManagerImpl.java:81)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:646)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:613)
at com.test.DSTester.main(DSTester.java:70)
The code works fine if i replace
ds.getConnection()
with
ds.getConnection("ora_user", "ora_password")
My issue is i need to get the connection without specifying login details for Oracle.
Please help me on this issue.
Any clue will be appreciated.
Thanks
I'd guess it would work if you retrieved the datasource from an application running on the WAS.
Try creating a servlet.
Context initialContext = new InitialContext();
DataSource dataSource = (DataSource) initialContext.lookup("EPLA1");
Connection con = dataSource.getConnection();
As within a servlet it is running within WAS it should be fine, if the "Test Connection" works. Running it outside is probably a different context.
I think you need to check all your configuration:
1) Is it application deplyed on cluster or into only one of cluster member?
2) JAAS - J2C authentication data - what is the scope?
Sometimes you need restar all your WAS environment. It depends on resource configuration scope
I'd recomend to you add resource refences for better configuration options.
SeeIBM Tech note
I am new in Java EJB 3.0. It is possible to call a (session) bean—deployed on JBoss—from a desktop application client?
Thanks in advance.
Yes you can. Some specifics are here (references EJB2 but it the same for EJB3 when it comes to remote clients): http://www.theserverside.com/discussions/thread.tss?thread_id=9197
Paraphrased:
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
env.put("java.naming.provider.url", "jnp://localhost:1099");
env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
Context ctx = new InitialContext(env);
// name is whatever JNDI name you gave it
Object o = ctx.lookup("home name");
EJBHome ejbHome = (EJBHome) PortableRemoteObject.narrow(o,EJBHome.class);
// This is userID should be the one passed.
EJB ejb = ejbHome.create(..);
Yes.
public static void main(String args[]) throws Exception {
InitialContext ctx = new InitialContext();
YourService yourService = (YourService) ctx.lookup("com.example.session.YourService");
String time = yourService.getTime();
System.out.println("Time is: " + time);
}
For client configuration you must provide jndi.properties file with contents
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
If you are looking for working examples on JBoss try download source code of Enterprise JavaBeans 3.0, Fifth Edition
Let's assume you have the following remote interface:
#Remote
public interface HelloBeanRemote {
public String sayHello();
}
And a session bean implementing it:
#Stateless
public class HelloBean implements HelloBeanRemote {
...
}
And that this EJB is correctly packaged and deployed on JBoss.
On the client side, create a jndi.properties with the following content and put it on the classpath:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost:1099
Then use the following code to call your EJB:
Context context;
try {
context = new InitialContext();
HelloBeanRemote beanRemote = (HelloBeanRemote)context.lookup("HelloBean/remote");
beanRemote.test();
} catch (NamingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
Alternatively, if you don't want to provide a jndi.properties file, you can explicitly setup the JNDI environment in the code and create the context like this:
Properties properties = new Properties();
properties.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
properties.put("java.naming.factory.url.pkgs","=org.jboss.naming:org.jnp.interfaces");
properties.put("java.naming.provider.url","localhost:1099");
Context context = new InitialContext(properties);
But I'd recommend using the jndi.properties for the sake of portability.
You can also expose the bean as a web service. I believe this is available as of EJB 3. It is quite nice considering you can do it with annotations. You may wish to consider using this option to decrease coupling. Here is a link to a tutorial.