//在BEAN里先写了个主函数测试BEANJSP用了应用服务器的缺省参数估计是JNDI配置问题
比如
Context.INITIAL_CONTEXT_FACTORY
Context.PROVIDER_URL
...
比如
Context.INITIAL_CONTEXT_FACTORY
Context.PROVIDER_URL
...
解决方案 »
- 关于word的预览功能怎么实现 求教
- struts2中select标签 选中某个值后页面内容刷新了 但是在select框里的值没变
- 输入sql语句,即时高亮关键字
- 关于上班时间统计的一个实现
- 如何在页面页面输出树形列表
- "/WEB-INF/struts-tiles.tld" not found 朋友们帮我看看,急啊
- 谁知道哪里有免费的jsp个人主页空间申请呀
- 新人求教:一组radioButton如何在jsp设置选中,如何在后台设置选中,如何实现readonly的状态,谢谢~
- 在jasperreport中如果数据中没有数据,如何显示空报表布满整个页面?
- java如何循环解析报文里面节点值
- 请教一个网页自动跳转的例子!就想csdn似的
- 救命啊!java 简体、繁体、英文、日文要在一个界面里显示,怎么解决
我用的服务器是TOMCAT,你说的JNDI的配置是什么意思
以前我有个BEAN也是那样写的,而且正常使用呢~~
不知道会不会影响,至少我的JSP文件能运行啊~
<Resource name="jdbc/xq" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/xq" >
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:microsoft:sqlserver://10.0.0.80:2433;DatabaseName=DB_8760db</value>
</parameter>
<parameter>
<name>username</name>
<value>sa</value>
</parameter>
<parameter>
<name>password</name>
<value>sqlserver</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>20</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>10</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>-1</value>
</parameter>
</ResourceParams>
</Context>这就是我在Server.xml里的配置,配置在JSP文件中正常使用~
System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY,"org.apache.naming.java.javaURLContextFactory");
如果有了这个javax.naming.Context.INITIAL_CONTEXT_FACTORY项,在new InitalContext()的时候就不会报出楼主的错误。从异常信息:Need to specify class name in environmen
t or system property, or as an applet parameter, or in an application resource f
ile中可以看出,传递javax.naming.Context.INITIAL_CONTEXT_FACTORY参数的值的方式。
2。你的DataSource是如何构造出来的?目前Tomcat推荐的是:
InitialContext cxt = new InitialContext();
DataSource ds = (DataSource) cxt.lookup( "java:/comp/env/jdbc/TestDB" );
3。由于属性是Tomcat启动时加载的,如果没有属性,需要研究有没有什么类修改过这项属性。
import javax.naming.*;
import javax.sql.DataSource;public class GetConn
{
public static synchronized Connection getConnection( ) throws Exception
{
try
{
Context initCtx = new javax.naming.InitialContext( );
Context envCtx = ( Context ) initCtx.lookup( "java:comp/env" );
DataSource ds = ( DataSource ) envCtx.lookup( "jdbc/xq" );
return ds.getConnection( );
}
catch( SQLException e )
{
throw e;
}
catch( NamingException e )
{
throw e;
}
}
}
System.getProperty("java.naming.factory.initial"),如果为null,那么你在这个web应用的jsp页面中肯定也无法获取到正确的InitialContext还是那句话,你的bean是怎么运行的?是采用jsp:useBean吗?如果是的话,在这个bean访问出错的web应用中,jsp页面能否正常获取到数据源?如果jsp页面也无法获取到数据源,报出同样的问题,说明你在conf\server.xml文件的配置出现了不同,在tomcat的context定义中,有一项属性useNaming,你是否设置为了false
<Context useNaming="false" />不知道这样解释是否清楚!
-------------------------------------
能,我说的JSP能访问,就是同一WEB应用System.getProperty("java.naming.factory.initial")的结果是org.apache.naming.java.javaURLContextFactory
NewsBean nb=new NewsBean()
这样用的
2。查看InitialContext.init(Hashtable)方法,下面是代码:
protected void init(Hashtable environment) throws NamingException {
myProps = ResourceManager.getInitialEnvironment(environment); if (myProps.get(Context.INITIAL_CONTEXT_FACTORY) != null) {
// user has specified initial context factory; try to get it
getDefaultInitCtx();
}
}
3。从上面的代码可以看出,一定是从getDefaultInitCtx()方法调用进去的,否则defaultInitCtx属性将为null,不会出现楼主遇到的异常。
4。下面是getDefaultInitCtx()方法
protected Context getDefaultInitCtx() throws NamingException{
if (!gotDefault) {
defaultInitCtx = NamingManager.getInitialContext(myProps);
gotDefault = true;
}
if (defaultInitCtx == null)
throw new NoInitialContextException(); return defaultInitCtx;
}
调用了NamingManager.getInitialContext()方法。
5。下面是NamingManager.getInitialContext()方法:
public static Context getInitialContext(Hashtable env)
throws NamingException {
InitialContextFactory factory; InitialContextFactoryBuilder builder = getInitialContextFactoryBuilder();
if (builder == null) {
// No factory installed, use property
// Get initial context factory class name String className = env != null ?
(String)env.get(Context.INITIAL_CONTEXT_FACTORY) : null;
if (className == null) {
NoInitialContextException ne = new NoInitialContextException(
"Need to specify class name in environment or system " +
"property, or as an applet parameter, or in an " +
"application resource file: " +
Context.INITIAL_CONTEXT_FACTORY);
throw ne;
} try {
factory = (InitialContextFactory)
helper.loadClass(className).newInstance();
} catch(Exception e) {
NoInitialContextException ne =
new NoInitialContextException(
"Cannot instantiate class: " + className);
ne.setRootCause(e);
throw ne;
}
} else {
factory = builder.createInitialContextFactory(env);
} return factory.getInitialContext(env);
}
异常出现了,就是从env中没有找到Context.INITIAL_CONTEXT_FACTORY对应的类名。
6。现在回来看历史代码,env=myProps,也就是关系到ResourceManager.getInitialEnvironment(environment);方法,其中的environment=null。
7。下面是ResourceManager.getInitialEnvironment(Hashtable)方法,也是我们分析的重点:
public static Hashtable getInitialEnvironment(Hashtable env)
throws NamingException
{
String[] props = VersionHelper.PROPS; // system/applet properties
if (env == null) {
env = new Hashtable(11);
}
Applet applet = (Applet)env.get(Context.APPLET); //applet肯定是null // Merge property values from env param, applet params, and system
// properties. The first value wins: there's no concatenation of
// colon-separated lists.
// Read system properties by first trying System.getProperties(),
// and then trying System.getProperty() if that fails. The former
// is more efficient due to fewer permission checks.
//
String[] jndiSysProps = helper.getJndiProperties();
for (int i = 0; i < props.length; i++) {
Object val = env.get(props[i]);
if (val == null) { //肯定进入这个分支
if (applet != null) { //肯定不进入这个分支
val = applet.getParameter(props[i]);
}
if (val == null) { //肯定进入这个分支
// Read system property.
val = (jndiSysProps != null)
? jndiSysProps[i]
: helper.getJndiProperty(i);
}
if (val != null) {
env.put(props[i], val);
}
}
} // Merge the above with the values read from all application
// resource files. Colon-separated lists are concatenated.
mergeTables(env, getApplicationResources());
return env;
}
下面是我个人的一下观察:
VersionHelper:
final static String[] PROPS = new String[] {
javax.naming.Context.INITIAL_CONTEXT_FACTORY,
javax.naming.Context.OBJECT_FACTORIES,
javax.naming.Context.URL_PKG_PREFIXES,
javax.naming.Context.STATE_FACTORIES,
javax.naming.Context.PROVIDER_URL,
javax.naming.Context.DNS_URL,
// The following shouldn't create a runtime dependence on ldap package.
javax.naming.ldap.LdapContext.CONTROL_FACTORIES
};
所以问题的关键就是谁实现了VersionHelper,但是由于JSP页面和你的类都会进入相同的逻辑代码(也就是同一个Web应用,默认的versionHelper的实现也是一个),所以我也不知道,你的问题到底出现在了哪里?而且我自己的代码例子中也没有出现楼主的现象。
final class VersionHelper12 extends VersionHelper { private boolean getSystemPropsFailed = false; VersionHelper12() {} // Disallow external from creating one of these. public Class loadClass(String className) throws ClassNotFoundException {
ClassLoader cl = getContextClassLoader();
return Class.forName(className, true, cl);
} /**
* Package private.
*/
Class loadClass(String className, ClassLoader cl)
throws ClassNotFoundException {
return Class.forName(className, true, cl);
} /**
* @param className A non-null fully qualified class name.
* @param codebase A non-null, space-separated list of URL strings.
*/
public Class loadClass(String className, String codebase)
throws ClassNotFoundException, MalformedURLException {
ClassLoader cl; ClassLoader parent = getContextClassLoader();
cl = URLClassLoader.newInstance(getUrlArray(codebase), parent); return Class.forName(className, true, cl);
} String getJndiProperty(final int i) {
return (String) AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
try {
return System.getProperty(PROPS[i]);
} catch (SecurityException e) {
return null;
}
}
}
);
} String[] getJndiProperties() {
if (getSystemPropsFailed) {
return null; // after one failure, don't bother trying again
}
Properties sysProps = (Properties) AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
try {
return System.getProperties();
} catch (SecurityException e) {
getSystemPropsFailed = true;
return null;
}
}
}
);
if (sysProps == null) {
return null;
}
String[] jProps = new String[PROPS.length];
for (int i = 0; i < PROPS.length; i++) {
jProps[i] = sysProps.getProperty(PROPS[i]);
}
return jProps;
} InputStream getResourceAsStream(final Class c, final String name) {
return (InputStream) AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
return c.getResourceAsStream(name);
}
}
);
} InputStream getJavaHomeLibStream(final String filename) {
return (InputStream) AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
try {
String javahome = System.getProperty("java.home");
if (javahome == null) {
return null;
}
String pathname = javahome + java.io.File.separator +
"lib" + java.io.File.separator + filename;
return new java.io.FileInputStream(pathname);
} catch (Exception e) {
return null;
}
}
}
);
} NamingEnumeration getResources(final ClassLoader cl, final String name)
throws IOException
{
Enumeration urls;
try {
urls = (Enumeration) AccessController.doPrivileged(
new PrivilegedExceptionAction() {
public Object run() throws IOException {
return (cl == null)
? ClassLoader.getSystemResources(name)
: cl.getResources(name);
}
}
);
} catch (PrivilegedActionException e) {
throw (IOException)e.getException();
}
return new InputStreamEnumeration(urls);
} ClassLoader getContextClassLoader() {
return (ClassLoader) AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
return Thread.currentThread().getContextClassLoader();
}
}
);
}
/**
* Given an enumeration of URLs, an instance of this class represents
* an enumeration of their InputStreams. Each operation on the URL
* enumeration is performed within a doPrivileged block.
* This is used to enumerate the resources under a foreign codebase.
* This class is not MT-safe.
*/
class InputStreamEnumeration implements NamingEnumeration { private final Enumeration urls; private Object nextElement = null; InputStreamEnumeration(Enumeration urls) {
this.urls = urls;
} /*
* Returns the next InputStream, or null if there are no more.
* An InputStream that cannot be opened is skipped.
*/
private Object getNextElement() {
return AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
while (urls.hasMoreElements()) {
try {
return ((URL)urls.nextElement()).openStream();
} catch (IOException e) {
// skip this URL
}
}
return null;
}
}
);
} public boolean hasMore() {
if (nextElement != null) {
return true;
}
nextElement = getNextElement();
return (nextElement != null);
} public boolean hasMoreElements() {
return hasMore();
} public Object next() {
if (hasMore()) {
Object res = nextElement;
nextElement = null;
return res;
} else {
throw new NoSuchElementException();
}
} public Object nextElement() {
return next();
} public void close() {
}
}
}
我解决了,非常感谢你的,至于原因嘛,我说出来都觉得丢脸!
1:我写了个MAIN函数去测试那个BEAN,它怎么可能调用TOMCAT的配置嘛,就等于运行一个JAVA文件
2:调用BEAN的JSP文件有两个错误,一少写个new Bean(....)的new,第2,我有个构造参数是int
结果,我忘记转换了气死我了,还烦恼了我两天
等会就结帖~,分太少,望谅解~