【问题标题】:Building Joda from source using IntelliJ?使用 IntelliJ 从源代码构建 Joda?
【发布时间】:2012-12-21 15:33:37
【问题描述】:

我已经导入了 Joda 源码 (https://github.com/JodaOrg/joda-time) 的 maven 项目并尝试构建该项目。当我这样做时,我得到以下堆栈跟踪:

线程“主”java.io.IOException 中的异常:找不到资源: “org/joda/time/tz/data/ZoneInfoMap”类加载器: sun.misc.Launcher$AppClassLoader@1f3e8d89 在 org.joda.time.tz.ZoneInfoProvider.openResource(ZoneInfoProvider.java:212) 在 org.joda.time.tz.ZoneInfoProvider.(ZoneInfoProvider.java:123) 在 org.joda.time.tz.ZoneInfoProvider.(ZoneInfoProvider.java:82) 在 org.joda.time.DateTimeZone.getDefaultProvider(DateTimeZone.java:462) 在 org.joda.time.DateTimeZone.setProvider0(DateTimeZone.java:416) 在 org.joda.time.DateTimeZone.(DateTimeZone.java:115) 在 org.joda.time.DateTimeUtils.(DateTimeUtils.java:48) 在 org.joda.time.base.BaseDateTime.(BaseDateTime.java:61) 在 org.joda.time.DateTime.(DateTime.java:155) 在 org.joda.time.MainTest.main(MainTest.java:12) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597) 在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

ZoneInfoProvider 类如下所示:

/*
 *  Copyright 2001-2009 Stephen Colebourne
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.joda.time.tz;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;

import org.joda.time.DateTimeZone;

/**
 * ZoneInfoProvider loads compiled data files as generated by
 * {@link ZoneInfoCompiler}.
 * <p>
 * ZoneInfoProvider is thread-safe and publicly immutable.
 *
 * @author Brian S O'Neill
 * @since 1.0
 */
public class ZoneInfoProvider implements Provider {

    /** The directory where the files are held. */
    private final File iFileDir;
    /** The resource path. */
    private final String iResourcePath;
    /** The class loader to use. */
    private final ClassLoader iLoader;
    /** Maps ids to strings or SoftReferences to DateTimeZones. */
    private final Map<String, Object> iZoneInfoMap;

    /**
     * ZoneInfoProvider searches the given directory for compiled data files.
     *
     * @throws IOException if directory or map file cannot be read
     */
    public ZoneInfoProvider(File fileDir) throws IOException {
        if (fileDir == null) {
            throw new IllegalArgumentException("No file directory provided");
        }
        if (!fileDir.exists()) {
            throw new IOException("File directory doesn't exist: " + fileDir);
        }
        if (!fileDir.isDirectory()) {
            throw new IOException("File doesn't refer to a directory: " + fileDir);
        }

        iFileDir = fileDir;
        iResourcePath = null;
        iLoader = null;

        iZoneInfoMap = loadZoneInfoMap(openResource("ZoneInfoMap"));
    }

    /**
     * ZoneInfoProvider searches the given ClassLoader resource path for
     * compiled data files. Resources are loaded from the ClassLoader that
     * loaded this class.
     *
     * @throws IOException if directory or map file cannot be read
     */
    public ZoneInfoProvider(String resourcePath) throws IOException {
        this(resourcePath, null, false);
    }

    /**
     * ZoneInfoProvider searches the given ClassLoader resource path for
     * compiled data files.
     *
     * @param loader ClassLoader to load compiled data files from. If null,
     * use system ClassLoader.
     * @throws IOException if directory or map file cannot be read
     */
    public ZoneInfoProvider(String resourcePath, ClassLoader loader)
        throws IOException
    {
        this(resourcePath, loader, true);
    }

    /**
     * @param favorSystemLoader when true, use the system class loader if
     * loader null. When false, use the current class loader if loader is null.
     */
    private ZoneInfoProvider(String resourcePath,
                             ClassLoader loader, boolean favorSystemLoader) 
        throws IOException
    {
        if (resourcePath == null) {
            throw new IllegalArgumentException("No resource path provided");
        }
        if (!resourcePath.endsWith("/")) {
            resourcePath += '/';
        }

        iFileDir = null;
        iResourcePath = resourcePath;

        if (loader == null && !favorSystemLoader) {
            loader = getClass().getClassLoader();
        }

        iLoader = loader;

        iZoneInfoMap = loadZoneInfoMap(openResource("ZoneInfoMap"));
    }

    //-----------------------------------------------------------------------
    /**
     * If an error is thrown while loading zone data, uncaughtException is
     * called to log the error and null is returned for this and all future
     * requests.
     * 
     * @param id  the id to load
     * @return the loaded zone
     */
    public DateTimeZone getZone(String id) {
        if (id == null) {
            return null;
        }

        Object obj = iZoneInfoMap.get(id);
        if (obj == null) {
            return null;
        }

        if (id.equals(obj)) {
            // Load zone data for the first time.
            return loadZoneData(id);
        }

        if (obj instanceof SoftReference<?>) {
            @SuppressWarnings("unchecked")
            SoftReference<DateTimeZone> ref = (SoftReference<DateTimeZone>) obj;
            DateTimeZone tz = ref.get();
            if (tz != null) {
                return tz;
            }
            // Reference cleared; load data again.
            return loadZoneData(id);
        }

        // If this point is reached, mapping must link to another.
        return getZone((String)obj);
    }

    /**
     * Gets a list of all the available zone ids.
     * 
     * @return the zone ids
     */
    public Set<String> getAvailableIDs() {
        // Return a copy of the keys rather than an umodifiable collection.
        // This prevents ConcurrentModificationExceptions from being thrown by
        // some JVMs if zones are opened while this set is iterated over.
        return new TreeSet<String>(iZoneInfoMap.keySet());
    }

    /**
     * Called if an exception is thrown from getZone while loading zone data.
     * 
     * @param ex  the exception
     */
    protected void uncaughtException(Exception ex) {
        Thread t = Thread.currentThread();
        t.getThreadGroup().uncaughtException(t, ex);
    }

    /**
     * Opens a resource from file or classpath.
     * 
     * @param name  the name to open
     * @return the input stream
     * @throws IOException if an error occurs
     */
    private InputStream openResource(String name) throws IOException {
        InputStream in;
        if (iFileDir != null) {
            in = new FileInputStream(new File(iFileDir, name));
        } else {
            String path = iResourcePath.concat(name);
            if (iLoader != null) {
                in = iLoader.getResourceAsStream(path);
            } else {
                in = ClassLoader.getSystemResourceAsStream(path);
            }
            if (in == null) {
                StringBuilder buf = new StringBuilder(40)
                    .append("Resource not found: \"")
                    .append(path)
                    .append("\" ClassLoader: ")
                    .append(iLoader != null ? iLoader.toString() : "system");
                throw new IOException(buf.toString());
            }
        }
        return in;
    }

    /**
     * Loads the time zone data for one id.
     * 
     * @param id  the id to load
     * @return the zone
     */
    private DateTimeZone loadZoneData(String id) {
        InputStream in = null;
        try {
            in = openResource(id);
            DateTimeZone tz = DateTimeZoneBuilder.readFrom(in, id);
            iZoneInfoMap.put(id, new SoftReference<DateTimeZone>(tz));
            return tz;
        } catch (IOException ex) {
            uncaughtException(ex);
            iZoneInfoMap.remove(id);
            return null;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
            }
        }
    }

    //-----------------------------------------------------------------------
    /**
     * Loads the zone info map.
     * 
     * @param in  the input stream
     * @return the map
     */
    private static Map<String, Object> loadZoneInfoMap(InputStream in) throws IOException {
        Map<String, Object> map = new ConcurrentHashMap<String, Object>();
        DataInputStream din = new DataInputStream(in);
        try {
            readZoneInfoMap(din, map);
        } finally {
            try {
                din.close();
            } catch (IOException ex) {
            }
        }
        map.put("UTC", new SoftReference<DateTimeZone>(DateTimeZone.UTC));
        return map;
    }

    /**
     * Reads the zone info map from file.
     * 
     * @param din  the input stream
     * @param zimap  gets filled with string id to string id mappings
     */
    private static void readZoneInfoMap(DataInputStream din, Map<String, Object> zimap) throws IOException {
        // Read the string pool.
        int size = din.readUnsignedShort();
        String[] pool = new String[size];
        for (int i=0; i<size; i++) {
            pool[i] = din.readUTF().intern();
        }

        // Read the mappings.
        size = din.readUnsignedShort();
        for (int i=0; i<size; i++) {
            try {
                zimap.put(pool[din.readUnsignedShort()], pool[din.readUnsignedShort()]);
            } catch (ArrayIndexOutOfBoundsException ex) {
                throw new IOException("Corrupt zone info map");
            }
        }
    }

}

另外值得注意的是 pom.xml 文件部分包含以下内容:

     <execution>
        <phase>compile</phase>
        <configuration>
          <target>
            <property name="tz.src" value="${project.build.sourceDirectory}/org/joda/time/tz/src" />
            <property name="tz.dst" value="${project.build.outputDirectory}/org/joda/time/tz/data" />
            <!--uptodate property="tz.build.notneeded" targetfile="${tz.dst}/ZoneInfoMap" >
              <srcfiles dir="${tz.src}" includes="**/*.*"/>
            </uptodate-->
            <mkdir dir="${tz.dst}" />
            <java classname="org.joda.time.tz.ZoneInfoCompiler" fork="true" failonerror="true">
              <classpath refid="maven.compile.classpath" />
              <sysproperty key="org.joda.time.DateTimeZone.Provider"

value="org.joda.time.tz.UTCProvider" /> 跑步

我不确定如何解决此问题。有什么建议吗?

【问题讨论】:

  • jodatime 的哪个版本?包含/链接 ZoneInfoProvider 的来源会有所帮助。我找到了一个,但我认为它不是同一个版本:grepcode.com/file/repo1.maven.org/maven2/joda-time/joda-time/…
  • 感谢@DanielKaplan。我正在使用 2.2 版(我认为...)
  • 我认为加载编译的数据文件存在一个普遍问题。
  • @DanielKaplan 还添加了可能相关的 pom.xml 的一部分。
  • 它正在寻找org/joda/time/tz/data/ZoneInfoMap 的资源路径。相对于您的工作目录是否存在?

标签: intellij-idea jodatime


【解决方案1】:

这可能发生在您错过初始化的情况下:

JodaTimeAndroid.init(this);

【讨论】:

  • m3dw3的评论表很重要。我忘记了这个电话并遇到了几个问题。将其添加到我的应用程序后,一切正常。
【解决方案2】:

进入运行配置 > 启动前 > 点击 + 号 > 点击 'maven goal' > 查找并添加 'joda time: compile'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-01
    • 2012-12-11
    • 2015-08-20
    • 2011-09-05
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多