【问题标题】:Java reflection and manifest file in jarjar 中的 Java 反射和清单文件
【发布时间】:2010-11-06 20:19:44
【问题描述】:

如果 jarA 在我的类路径中,我想(而且我不知道是否可能)做某事,如果 jarB 在我的类路径中,我想做其他事情。我不会在 Netbeans 项目库引用中指定这些 jar,因为我不知道将使用哪些 jar。

现在,当我尝试通过反射使用 jar 的类时,在我的 Netbeans 项目库引用中包含该 jar 即可。但是当我删除 netbeans 项目库引用但将 jar 添加到我的类路径时,反射不起作用。

我的问题真的是 1) 这可以做到吗? 2)我是否正确地考虑它 3)当我指定 -cp 或 -classpath 以包含包含它不起作用的 jar 的目录时,为什么会这样? 4) 为什么我在jar文件中的manifest.mf中指定目录时它不起作用?

请告诉我。这真的很困扰我。

谢谢, 朱利安

【问题讨论】:

  • 你没有使用 -jar 是吗? (它会默默地忽略类路径。)
  • 我正在使用 java -jar...好吧,这是有道理的...但我仍然进入 manifest.mf 文件并将其更改为使用我的目录,但它没有工作...仍然试图弄清楚发生了什么,会及时通知你。

标签: java reflection jar manifest


【解决方案1】:

关于第 3 点 - 您应该在类路径中包含完全限定的 jar 名称,而不仅仅是目录。

【讨论】:

  • 但是 java 帮助选项说类路径搜索目录路径
  • "-classpath A ; 用于搜索类文件的目录、JAR 档案和 ZIP 档案的分隔列表"。您的评论只是部分正确 - 它适用于类文件,但不适用于 jar 文件。类路径中对 Jar 文件的任何引用都必须是完全限定的
【解决方案2】:

我相信!

ClassLoader.getSystemClassLoader()getURLs();

这将告诉您哪些 Jar 文件在您的类路径中。然后随心所欲地做 X 或 Y。

【讨论】:

  • 糟糕,可能不是很清楚。很高兴知道哪些 jar 文件在我的类路径中,但是在我确定必须使用找到的 jar 之后。
  • 我可能需要更多解释。问题是您的类路径中的两个不同的 JAR 文件中可能存在相同的类吗?在这种情况下,在它们之间进行选择可能会很棘手。 findClass(因此 loadClass)可能只会采用它找到的第一个。如果您有两个 JAR 文件并且想要为您的类选择源,最好使用 File 函数自己搜索它们,然后创建您自己的类加载器。你想要一个例子吗?我在某处有一些代码。您可以动态加载不在您的类路径中的 JAR 文件。
【解决方案3】:

类路径可以引用包含 .class 文件的目录,也可以直接引用 .jar 文件。如果它引用包含 .jar 文件的目录,则不会包含它们。


java -help 说这个关于-classpath:“目录列表,JAR 档案, 和 ZIP 档案来搜索 类文件。" 很明显,在类路径上的目录中搜索的是类文件,而不是 JAR 档案。

【讨论】:

    【解决方案4】:

    这就是我的做法。 内部类 封装了记录器的单例实例及其跟踪方法(呵呵——我知道——单例中的单例)。 外部类仅在可以加载特殊类时才使用它,否则我们继续没有它。希望您可以修改它以满足您的需求。任何关于更好代码的建议都会受到赞赏! :-) HTH

    import java.lang.reflect.Method;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * Provides centralized access to standardized output formatting. Output is sent to System.out and,
     * if the classpath allows it, to the Cisco CTIOS LogManager.  (This is NOT a dependency, however.)
     * 
     */
    public class LogWriter
    {
        protected static LogWriter me = null;
        private SimpleDateFormat dateFormat = null;
        private StringBuffer line = null;
        CLogger ciscoLogger = null;
    
        /*
         * The following 2 methods constitute the thread-safe singleton pattern.
         */
        private static class LogWriterHolder 
        {
            public static LogWriter me = new LogWriter();
        }
        /**
         * Returns singleton instance of the class.  Thread-safe.  The only way to get one is to use this.
         * 
         * @return an instance of LogWriter
         */
        public static LogWriter sharedInstance() 
        {
            return LogWriterHolder.me;
        }
    
    
        @SuppressWarnings("unchecked")
        LogWriter() 
        {
            dateFormat = new SimpleDateFormat("yyyyMMddHHmmss ");
            line = new StringBuffer();
            try {
                Class x = Class.forName("com.cisco.cti.ctios.util.LogManager");
                if( x != null ) {
                    java.lang.reflect.Method m = x.getMethod("Instance", new Class[0]);
                    java.lang.reflect.Method n  = x.getMethod("Trace", int.class, String.class );
                    if( m != null ) {
                         Object y = m.invoke( x , new Object[0] );
                         if( n != null ) {
                             ciscoLogger = new CLogger();
                             ciscoLogger.target = y;
                             ciscoLogger.traceImpl = n ;
                         }
                    }
                }
            } catch(Throwable e ) 
            {
                System.err.println( e.getMessage() ) ;
                e.printStackTrace();
            }
        }
    
        /**
         * Formats a line and sends to System.out.  The collection and formatting of the text is 
         * thread safe.
         * 
         * @param message       The human message you want to display in the log (required).
         * @param hostAddress   Host address of server (optional)
         * @param hostPort      Port on hostAddresss (optional) - also used for className in object-specific logs.
         */
        public void log( String message, String hostAddress, String hostPort ) 
        {
            if ( message == null || message.length() < 3 ) return;
    
            synchronized( this ) 
            {
                try {
                    line.delete(0, line.length());
                    line.append(dateFormat.format(new Date()));
                    line.append(hostAddress);
                    line.append(":");
                    line.append(hostPort);
                    line.append(" ");
                    while (line.length() < 28)
                        line.append(" ");
                    line.append(message);
    
                    this.write( line.toString() );
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        private void write(String line )
        {
            System.out.println( line ) ;
        }
    
        /**
         * Write a simple log message to output delegates (default is System.out).
         * <p>
         * Will prepend each line with date in yyyyMMddHHmmss format.  there will be a big space
         * after the date, in the spot where host and port are normally written, when {@link LogWriter#log(String, String, String) log(String,String,String)}
         * is used.
         * 
         * @param message What you want to record in the log.
         */
        public void log( String message )
        {
            if( ciscoLogger != null ) ciscoLogger.trace(0x01, message );
            this.log( message, "", "");
        }
    
        class CLogger
        {
            Object target;
            Method traceImpl;
    
            @SuppressWarnings("boxing")
            public void trace( int x, String y )
            {
                try {
                    traceImpl.invoke( target, x, y) ;
                } catch( Throwable e ) {
                    // nothing to say about this
                }
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2013-10-21
      • 2016-10-03
      • 2011-02-11
      • 2015-11-20
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 2016-08-19
      • 1970-01-01
      相关资源
      最近更新 更多