//在BEAN里先写了个主函数测试BEANJSP用了应用服务器的缺省参数估计是JNDI配置问题
比如
Context.INITIAL_CONTEXT_FACTORY
Context.PROVIDER_URL
...

解决方案 »

  1.   

    楼上,怎么解决啊,我不太明白你的意思啊
    我用的服务器是TOMCAT,你说的JNDI的配置是什么意思
    以前我有个BEAN也是那样写的,而且正常使用呢~~
      

  2.   

    不过有些变动,原来的数据库连接池是配置的ROOT目录,现在配置的是自己建的虚拟目录
    不知道会不会影响,至少我的JSP文件能运行啊~
      

  3.   

    <Context path="/bqll" docBase="bqll" debug="0" reloadable="true" crossContext="true">
              <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文件中正常使用~
      

  4.   

    很奇怪啊,楼主的应用服务器是什么,BEAN又是怎么运行的?以Tomcat应用服务器为例,在Tomcat启动的时候会向系统属性中添加一个属性(默认的web应用):
    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参数的值的方式。
      

  5.   

    我有下面几个问题,麻烦楼主回答一下。1。目前你的JVM属性中有没有java.naming.factory.initial一项属性,利用System.getProperty()可以获取出属性来,这项属性是什么?
    2。你的DataSource是如何构造出来的?目前Tomcat推荐的是:
    InitialContext cxt = new InitialContext();
    DataSource ds = (DataSource) cxt.lookup( "java:/comp/env/jdbc/TestDB" );
    3。由于属性是Tomcat启动时加载的,如果没有属性,需要研究有没有什么类修改过这项属性。
      

  6.   

    好的,先谢谢,但你要完全明白我已经给出的信息~~out.println(System.getProperty());    //这样???要抱错啊DBConn文件如下:package dqh.DBConn;import java.sql.*;
    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;
              }
         }
    }
      

  7.   

    楼上的老兄,System.getProperty()是需要参数的:
    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" />不知道这样解释是否清楚!
      

  8.   

    还是那句话,你的bean是怎么运行的?是采用jsp:useBean吗?如果是的话,在这个bean访问出错的web应用中,jsp页面能否正常获取到数据源?
    -------------------------------------
    能,我说的JSP能访问,就是同一WEB应用System.getProperty("java.naming.factory.initial")的结果是org.apache.naming.java.javaURLContextFactory
      

  9.   

    <%@ page import="dqh.news.NewsBean" %>然后
    NewsBean nb=new NewsBean()
    这样用的
      

  10.   

    我无法重现你的现象,我也没有办法找到新的解决办法,下面是我对JDK这部分代码的研究,请你根据下面的步骤自己来判断一下到底问题在哪里,很抱歉!1。查看类javax.naming.InitialContext的构造方法,new InitialContext()方法,里面执行init(null);
    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的实现也是一个),所以我也不知道,你的问题到底出现在了哪里?而且我自己的代码例子中也没有出现楼主的现象。
      

  11.   

    我看了一下,是JDK中的VersionHelper12实现了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() {
    }
        }
    }
      

  12.   

    TO:bison_java(Java野牛) (
    我解决了,非常感谢你的,至于原因嘛,我说出来都觉得丢脸!
    1:我写了个MAIN函数去测试那个BEAN,它怎么可能调用TOMCAT的配置嘛,就等于运行一个JAVA文件
    2:调用BEAN的JSP文件有两个错误,一少写个new Bean(....)的new,第2,我有个构造参数是int
    结果,我忘记转换了气死我了,还烦恼了我两天
    等会就结帖~,分太少,望谅解~