jar中的Java反射和清单文件

时间:2009-06-29 22:18:00

标签: java reflection jar manifest

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

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

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

请告诉我。这真让我烦恼。

谢谢, 儒略

4 个答案:

答案 0 :(得分:1)

第3点的

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

答案 1 :(得分:1)

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


java -help说明-classpath:“目录列表,JAR档案, 和ZIP存档搜索以获取类文件。“这很清楚,类路径上的目录是搜索类文件,而不是JAR存档。

答案 2 :(得分:1)

我相信!

ClassLoader.getSystemClassLoader()getURLs();

这将告诉您类路径中有哪些Jar文件。然后随意做X或Y.

答案 3 :(得分:0)

这就是我的做法。 内部类封装了记录器的单例实例及其跟踪方法(嘿 - 我知道 - 单例内的单例)。如果可以加载特殊类,外部类仅使用它,否则我们继续使用它。希望您可以根据自己的需要进行修改。任何关于更好的代码的建议总是受到赞赏! :-) 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
            }
        }
    }

}