Получение MalformedURLException в моих тестах, но это никогда не происходило раньше - PullRequest
0 голосов
/ 07 мая 2018

Я обновил свои окна с 7 до 10, и теперь в моем проекте я получаю эти исключения при выполнении тестов.

Вот мой код

    @BeforeClass
public static void createSchema() throws Exception {

    log.info("Creating H2 CA_MANAGER schema");

    URL schemaDDL = Thread.currentThread().getContextClassLoader().getResource("create_cam_test.sql");
    RunScript.execute(TestConfig.URL,
            TestConfig.USER, TestConfig.PASSWORD, schemaDDL.getFile(), null, false);

    log.info("Running H2 CA_MANAGER DDL");

    URL ddl = Thread.currentThread().getContextClassLoader().getResource("ca_manager3_ddl_h2.sql");
    RunScript.execute(TestConfig.URL,
            TestConfig.USER, TestConfig.PASSWORD, ddl.getFile(), null, false);
}

Вот исключение.

 org.h2.message.DbException: IO Exception: "java.net.MalformedURLException: no protocol: /C:/Users/Documents/camanager-combined/camanager.persistence.hibernate/target/test-classes/create_cam_test.sql"; "/C:/Users/Documents/camanager-combined/camanager.persistence.hibernate/target/test-classes/create_cam_test.sql" [90031-196]

    at org.h2.message.DbException.get(DbException.java:168)
    at org.h2.message.DbException.convertIOException(DbException.java:330)
    at org.h2.tools.RunScript.process(RunScript.java:334)
    at org.h2.tools.RunScript.execute(RunScript.java:304)
    at 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.h2.jdbc.JdbcSQLException: IO Exception: "java.net.MalformedURLException: no protocol: /C:/Users/Documents/camanager-combined/camanager.persistence.hibernate/target/test-classes/create_cam_test.sql"; "/C:/Users/Documents/camanager-combined/camanager.persistence.hibernate/target/test-classes/create_cam_test.sql" [90031-196]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
    ... 27 more
Caused by: java.net.MalformedURLException: no protocol: /C:/Users/Documents/camanager-combined/camanager.persistence.hibernate/target/test-classes/create_cam_test.sql
    at java.net.URL.<init>(URL.java:593)
    at java.net.URL.<init>(URL.java:490)
    at java.net.URL.<init>(URL.java:439)
    at org.h2.store.fs.FilePathDisk.newInputStream(FilePathDisk.java:317)
    at org.h2.store.fs.FileUtils.newInputStream(FileUtils.java:218)
    at org.h2.tools.RunScript.process(RunScript.java:186)
    at org.h2.tools.RunScript.process(RunScript.java:329)
    ... 24 more

Исключение возникает, когда я хочу выполнить скрипт. Переменная schemaDDL.getFile() возвращает путь точно так, как показано в исключении:

/C:/Users/Documents/camanager-combined/camanager.persistence.hibernate/target/test-classes/create_cam_test.sql

Я тоже проверил, он точно есть. Я также нашел решения, в которых указано, что file:// необходимо добавить к пути, я так и сделал, и все равно возникает то же исключение. Путь к файлу выглядит следующим образом

file://C:/Users/Documents/camanager-combined/camanager.persistence.hibernate/target/test-classes/create_cam_test.sql

Исключение выглядит следующим образом

org.h2.jdbc.JdbcSQLException: IO Exception: "java.net.MalformedURLException: no protocol: //C:/Users/Documents/camanager-combined/camanager.persistence.hibernate/target/test-classes/create_cam_test.sql"; "file://C:/Users/Documents/camanager-combined/camanager.persistence.hibernate/target/test-classes/create_cam_test.sql" [90031-196]

Я использую Java-версию Java 1.8.0_121. Есть ли у вас какие-либо решения.

1 Ответ

0 голосов
/ 07 мая 2018

Проблема в том, что

/C:/Users/francois17/Documents/.../create_cam_test.sql

не является URL. Это путь.

Итак, вопрос в том, почему это вызывает эту проблему?

Теперь похоже, что это происходит из-за этого вызова:

RunScript.execute(TestConfig.URL,
        TestConfig.USER, TestConfig.PASSWORD, schemaDDL.getFile(), null, false);

или этот

RunScript.execute(TestConfig.URL,
        TestConfig.USER, TestConfig.PASSWORD, ddl.getFile(), null, false);

Это выглядит нормально, потому что API для execute ожидает, что 4-й аргумент будет путевым именем.

Тогда я посмотрел на сайт, на котором создается URL. Это в org.h2.store.FileDiskPath::newInputStream. Код для метода:

public InputStream  newInputStream() throws IOException {
    if (name.indexOf(':') > 1) {
        // if the : is in position 1, a windows file access is assumed: C:.. or D:
        if (name.startsWith(CLASSPATH_PREFIX)) {
            String fileName = name.substring(CLASSPATH_PREFIX.length());
            if (!fileName.startsWith("/")) {
                fileName = "/" + fileName;
            }
            InputStream in = getClass().getResourceAsStream(fileName);
            if (in == null) {
                 Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
            }
            if (in == null) {
                throw new FileNotFoundException("resource " + fileName);
            }
            return in;
        }
        // otherwise an URL is assumed
        URL url = new URL(name);
        InputStream in = url.openStream();
        return in;
    }
    FileInputStream in = new FileInputStream(name);
    IOUtils.trace("openFileInputStream", name, in);
    return in;
}

Подводя итог, что он делает:

  1. ищет двоеточие в пути
  2. Если двоеточие не является вторым символом:
    1. он ищет URL "classpath:" и обрабатывает его.
    2. в противном случае, он открывает URL как обычный URL
  3. Если двоеточия не было или двоеточие было вторым символом (то есть символом диска Windows), он открывает объект в виде файла.

LIGHTBULB!

Посмотрите внимательно на путь сверху. Он выглядит как путь, но на самом деле он искажен. Путь к Windows с диска НЕ ​​ДОЛЖЕН начинаться с «/». Это дополнительное "/" приводит к тому, что двоеточие становится третьим символом, что нарушает логику метода newInputStream.

Правильный формат для пути с диском следующий:

C:/Users/francois17/Documents/.../create_cam_test.sql

Найдите, откуда появился этот фальшивый ведущий "/", и вы, вероятно, решили свою проблему. Вы также можете обойти фиктивную «/», либо удалив ее, либо добавив «file: //». (Примечание: 2 косые черты ... потому что они уже есть!)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...