如何在Eclipse中导出到Runnable Jar时维护文件夹结构?

时间:2017-10-02 12:42:38

标签: java maven selenium jar cucumber

我试图在过去的一周内找到解​​决方案,并发布了一个相同的问题。

我创建了一个简单的Maven项目。 并编写了一个开放浏览器的功能文件,转到Facebook并关闭浏览器。

首先,下面是项目结构,

Project Structure

以下是我的功能文件。要素文件的名称为 Testing.feature

Feature: Open FB
Scenario: Open FB
    Given User opens "facebookURL" on "ChromeBr"
    When User is on facebook
    Then close the browser

然后我为上面的特征文件编写了一个步骤定义。步骤定义文件的名称是 Testing.java

package stepDefinitions;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import util.WebConnector;

public class Testing {
    WebConnector wc = WebConnector.getInstance();
    @Given("^User opens \"([^\"]*)\" on \"([^\"]*)\"$")
    public void user_opens_on(String URL, String Browser) throws Throwable {
        wc.openBrowser(Browser);
        wc.navigateURL(URL);
        System.out.println("Browser Opened & navigated to FB");
    }


    @When("^User is on facebook$")
    public void user_is_on_facebook() throws Throwable {
        System.out.println("User is on FB");
    }

    @Then("^close the browser$")
    public void close_the_browser() throws Throwable {
        wc.quitBrowser();
        System.out.println("Browser Closed");
    }
}

config.properties只包含一个属性

facebookURL=https://www.facebook.com

我编写了一个公共类文件,它是 WebConnector.java ,它有一个用于初始化属性文件的构造函数和一些方法,比如打开浏览器和URL等

package util;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class WebConnector {
    public Properties OR = null;
    public Properties CONFIG = null;
    public static WebDriver driver;
    static WebConnector w;
    private WebConnector() {
        if(CONFIG==null) {
            try {
                CONFIG = new Properties();
                FileInputStream fis = new FileInputStream(System.getProperty("user.dir")+"\\src\\test\\java\\config\\config.properties"); **//Here only I get error when I export as Runnable Jar and Run**
                CONFIG.load(fis);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public static WebConnector getInstance() {
        if(w==null)
            w=new WebConnector();
            return w;
    }

    public void openBrowser(String browserName) throws IOException {
            System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"\\chromedriver.exe");
            driver = new ChromeDriver();
            driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
    }
    public void navigateURL(String URL) throws IOException {
        driver.get(CONFIG.getProperty(URL));
    }

    public void quitBrowser() {
        driver.quit();
    }
}

这是我的测试运行器类,它有一个main方法。它可以使用Junit以及Java Application

运行
package util;

import org.junit.runner.JUnitCore;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(
        features = "classpath:feature",
        glue = "stepDefinitions"
        )

public class RunCukesTest {
    public static void main(String[] args) {                    
        JUnitCore.main("util.RunCukesTest");
    }
}

的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>Jar_Testing</groupId>
  <artifactId>Jar_Testing</artifactId>
  <version>0.0.1-SNAPSHOT</version>


    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/info.cukes/cucumber-java -->
        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/info.cukes/cucumber-core -->
        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-core</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/info.cukes/cucumber-junit -->
        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>1.2.5</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
            <plugins>
                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <archive>
                            <manifest>
                                <mainClass>util.RunCukesTest</mainClass>
                            </manifest>
                        </archive>
                    </configuration>
                </plugin>
            </plugins>
    </build>

</project>

问题: 当我使用Junit或Java Application运行RunCukesTest.java时,它运行得很好。也就是说,它打开浏览器,转到fb并关闭浏览器。

但是当我创建一个可执行的Jar并运行时,它没有按预期运行。

按照以下步骤导出为Runnable Jar:

1) Run--> Run Configuration--> Java Application-->New Launch Configuration-->And selects the main class as RunCukesTest.java-->Apply
2) Right click the project-->Export
3) Java--> Runnable JAR File -->Next
4) Under Launch Configuration select the RunCukesTest.java and give the export destination
5) And I have selected the option "Extract required Libraries into Jar"
5) click finish

假设我已将此Jar保存在我的桌面中。桌面路径 - &gt;“C:\ Users \ PC \ Desktop” 当我从命令提示符运行此Jar时,它显示以下

C:\Users\PC\Downloads>java -jar Maven.jar
JUnit version 4.12
.java.io.FileNotFoundException: C:\Users\PC\Downloads\src\test\java\config\c
onfig.properties (The system cannot find the path specified)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(FileInputStream.java:195)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at java.io.FileInputStream.<init>(FileInputStream.java:93)
        at util.WebConnector.<init>(WebConnector.java:19)
        at util.WebConnector.getInstance(WebConnector.java:30)
        at stepDefinitions.Testing.<init>(Testing.java:9)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstruct
orAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingC
onstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at cucumber.runtime.java.DefaultJavaObjectFactory.cacheNewInstance(Defau
ltJavaObjectFactory.java:41)
        at cucumber.runtime.java.DefaultJavaObjectFactory.getInstance(DefaultJav
aObjectFactory.java:33)
        at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.j
ava:38)
        at cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java
:37)
        at cucumber.runtime.Runtime.runStep(Runtime.java:300)
        at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
        at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
        at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:44)

        at cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.ja
va:102)
        at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63)
        at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18)
        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 cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70)
        at cucumber.api.junit.Cucumber.runChild(Cucumber.java:95)
        at cucumber.api.junit.Cucumber.runChild(Cucumber.java:38)
        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 cucumber.api.junit.Cucumber.run(Cucumber.java:100)
        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 org.junit.runner.JUnitCore.run(JUnitCore.java:115)
        at org.junit.runner.JUnitCore.runMain(JUnitCore.java:77)
        at org.junit.runner.JUnitCore.main(JUnitCore.java:36)
        at util.RunCukesTest.main(RunCukesTest.java:16)
.EEII
←[31mFailed scenarios:←[0m
←[31mfeature/Testing.feature:3 ←[0m# Scenario: Open FB

1 Scenarios (←[31m1 failed←[0m)
3 Steps (←[31m1 failed←[0m, ←[36m2 skipped←[0m)
0m0.314s

java.lang.IllegalStateException: The driver executable does not exist: C:\Users\
PC\Downloads\chromedriver.exe
        at com.google.common.base.Preconditions.checkState(Preconditions.java:53
4)
        at org.openqa.selenium.remote.service.DriverService.checkExecutable(Driv
erService.java:136)
        at org.openqa.selenium.remote.service.DriverService.findExecutable(Drive
rService.java:131)
        at org.openqa.selenium.chrome.ChromeDriverService.access$000(ChromeDrive
rService.java:32)
        at org.openqa.selenium.chrome.ChromeDriverService$Builder.findDefaultExe
cutable(ChromeDriverService.java:137)
        at org.openqa.selenium.remote.service.DriverService$Builder.build(Driver
Service.java:329)
        at org.openqa.selenium.chrome.ChromeDriverService.createDefaultService(C
hromeDriverService.java:88)
        at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:124)

        at util.WebConnector.openBrowser(WebConnector.java:36)
        at stepDefinitions.Testing.user_opens_on(Testing.java:12)
        at ?.Given User opens "facebookURL" on "ChromeBr"(feature/Testing.featur
e:4)


Time: 0.359
There were 2 failures:
1) Given User opens "facebookURL" on "ChromeBr"(Scenario: Open FB)
java.lang.IllegalStateException: The driver executable does not exist: C:\Users\
PC\Downloads\chromedriver.exe
        at com.google.common.base.Preconditions.checkState(Preconditions.java:53
4)
        at org.openqa.selenium.remote.service.DriverService.checkExecutable(Driv
erService.java:136)
        at org.openqa.selenium.remote.service.DriverService.findExecutable(Drive
rService.java:131)
        at org.openqa.selenium.chrome.ChromeDriverService.access$000(ChromeDrive
rService.java:32)
        at org.openqa.selenium.chrome.ChromeDriverService$Builder.findDefaultExe
cutable(ChromeDriverService.java:137)
        at org.openqa.selenium.remote.service.DriverService$Builder.build(Driver
Service.java:329)
        at org.openqa.selenium.chrome.ChromeDriverService.createDefaultService(C
hromeDriverService.java:88)
        at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:124)

        at util.WebConnector.openBrowser(WebConnector.java:36)
        at stepDefinitions.Testing.user_opens_on(Testing.java:12)
        at ?.Given User opens "facebookURL" on "ChromeBr"(feature/Testing.featur
e:4)
2) Scenario: Open FB
java.lang.IllegalStateException: The driver executable does not exist: C:\Users\
PC\Downloads\chromedriver.exe
        at com.google.common.base.Preconditions.checkState(Preconditions.java:53
4)
        at org.openqa.selenium.remote.service.DriverService.checkExecutable(Driv
erService.java:136)
        at org.openqa.selenium.remote.service.DriverService.findExecutable(Drive
rService.java:131)
        at org.openqa.selenium.chrome.ChromeDriverService.access$000(ChromeDrive
rService.java:32)
        at org.openqa.selenium.chrome.ChromeDriverService$Builder.findDefaultExe
cutable(ChromeDriverService.java:137)
        at org.openqa.selenium.remote.service.DriverService$Builder.build(Driver
Service.java:329)
        at org.openqa.selenium.chrome.ChromeDriverService.createDefaultService(C
hromeDriverService.java:88)
        at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:124)

        at util.WebConnector.openBrowser(WebConnector.java:36)
        at stepDefinitions.Testing.user_opens_on(Testing.java:12)
        at ?.Given User opens "facebookURL" on "ChromeBr"(feature/Testing.featur
e:4)

FAILURES!!!
Tests run: 2,  Failures: 2

我知道它正在尝试找到该文件,但它失败了。当我打开Jar时,它位于以下结构中。

Jar Structure after Exporting

如何保持相同的文件夹结构,以便我找不到文件未找到异常或是否有其他方法可以成功运行此文件?

3 个答案:

答案 0 :(得分:0)

这不是jar结构的问题,而是关于读取位置来查找文件。

假设您有一个简单的java文件,其代码(伪)如下所示:

  1. 获取最新目录
  2. 在当前目录中查找名为src / test / java / config的子目录
  3. 如果找不到目录,则抛出异常。
  4. 现在,如果您从IDE(eclipse)运行Main类,那么您拥有"src"文件夹和所有必需的sub folders。因此,不会有例外。

    但是如果你创建一个jar,并将jar放在另一个&#34;新文件夹中#34; (例如jarFolder),然后当你运行代码时,你会看到找不到异常目录。 那是显而易见

    所以这取决于你,只有你遵循你想要的方法。

    1)有些人带有jar的properties / config文件(当配置文件的内容是动态的并且需要更改时,最不推荐。)

    2)有些人将他们的配置文件保留在配置层之下,然后在你复制jar的任何地方,创建一个配置文件夹并将配置文件放在那里。在这种情况下,您可能必须像

    一样阅读

    System.getProperty("user.dir")+File.separator+"config"+File.separator+"config.properties"; // Offcourse, using \\ is a bad way to use File.separtor as it will not work on unix again

    3)另一件事,我建议人们不要购买他们的&#34; src&#34;但他们的二进制文件通常驻留在类文件夹中,而不是在src文件夹中。因此,应避免将src文件夹中的任何内容放入二进制jar中。

答案 1 :(得分:0)

我的建议是,您可以使用批处理文件运行jar文件。

首先,您可以使用maven build创建项目的jar文件。以下是步骤

右键单击Maven项目 - &gt;运行方式 - &gt; Maven构建 - &gt;在目标中给出清洁包 - &gt;运行

成功执行后,将在项目的目标文件夹中创建jar文件。现在在项目位置创建一个批处理文件,如run.bat。以下是您需要在批处理文件中编写的代码

java -Xms512m -Xmx512m -jar execute.jar -0 true
pause

您可以更改jar名称。现在转到批处理文件位置并双击它。您的项目将执行,控制台报告将显示在命令提示符中。

答案 2 :(得分:0)

我们不能保持项目的相同结构。最好的解决方案,我发现,当从任何其他路径运行可执行jar时,我确保那些文件夹(不是jar的一部分,但是项目的一部分)存在于我的可执行jar的相同路径中。