简体   繁体   中英

VSCode: how to share .java files between projects

I am fairly new to Java so might be missing the obvious here.

I want to pull .java files (not jars ) from a folder that is "external" to the Project. I am developing the MainProject and the Shared java files concurrently. Later I will want to use the Shared files in another Project (most likely also as .java files since that other Project will be related to the first - ie more concurrent development. ;-)

I can't work out how to use a .java file from the SharedJava folder in the MainProject. I have tried what is suggested in SO etc to no avail.

I have set up a new project with folders like so:

在此处输入图像描述

I have created VSCode Java Projects in both folders, although for the SharedJava I didn't include any build tools. Maybe that is an issue?

Both projects appear in the JAVA PROJECTS section in VSCode.

Expanded, it looks like below, and as an initial test the highlighted java file is the one I would like to import into the MainProject.

在此处输入图像描述

The SharedClass.java file:

package messaging;

public class SharedClass {
  public void echoMessage(String msg) {
    System.out.println("SharedClass.echoMessage() said: " + msg);
  }
}

and what I am trying to do for my test is in this MainProject App.java file:

package com.flowt;

public class App {
    public static void main( String[] args ) {
        System.out.println( "Hello World!" );

        // How to import SharedClass ?
        SharedClass sharedClass = new SharedClass();
        sharedClass.echoMessage("Hello XYZ");
    }
}

My MainProject.code-workspace file is this:

{
    "folders": [
        {
            "path": "."
        },
        {
            "path": "../SharedJava/flowtshared"
        }
    ],
    "settings": {
        "java.project.sourcePaths": [
            "src",
            "../SharedJava/flowtshared/src"
        ]
    }
}

So, what do I need to do to be able to import SharedClass.java into MainProject? (without creating a symlink!)

Thanks, Murray

Ok. Got it working.

Firstly: The best explanation I found for understanding Maven (that included a good example of multi-module projects) is here: https://books.sonatype.com/mvnex-book/reference/index.html

It is quite old, and the sample code wont work because it references APIs that no longer exist. However, the explanations are really clear and the sample code files still exist as a reference.

Maybe if you know of more up-to-date references that are as good, you can put a comment below.

For other Java newbies I offer the following...

The final result was done partly using VSCode functionality and partly hand customised. If I understood the VSCode java extensions better maybe I could have done it all using the extensions.

The short version is as below and the resulting files and folders etc are shown further down.

  1. Create a new Java Project for the parent . Use the Maven quick-start archetype. For this sample I just used all the defaults, apart from my groupId, etc.

  2. Keep the pom.xml file and delete the rest.

  3. Add <packaging>pom</packaging> to the pom.xml file as per example below.

  4. Inside the parent project, create the shared project, using the same groupId as the parent. When asked, add the project to the workspace. Delete the App.java file if you wish.

  5. In the shared pom.xml I removed the <groupId> section. Note that Maven includes the <parent> block.

  6. Inside the parent project, create the mainapp project, using the same groupId as the parent. When asked, add the project to the workspace.

  7. In the mainapp pom.xml I removed the <groupId> section. Note that Maven includes the <parent> block.

  8. In the mainapp pom.xml, add a <dependency> block for the shared project, as per example below.

  9. If you go back to the parent project's pom.xml , and scroll to the end, you should see that VSCode has added a block like this:

<modules>
  <module>shared</module>
  <module>mainapp</module>
</modules>

which you can move to the top to make it more visible.

  1. Add your test class (eg PrintMessage.java) to your shared project in its own folder (eg messaging).
  2. Update your mainapp App.java file to include your shared class as per the example.
  3. From the parent project root run mvn clean install . This adds the jars to the local Maven repo (the location of the local repo is as printed in the terminal output).

At this point I find I needed to close and reopen the VSCode window so that the Java Projects section sorts itself out and the 3 projects appear there. If I didn't do that I got "classpath" errors.

Then, I could test by opening the App.java file and using VSCode to Run java . The terminal shows:

Hello World!
PrintMessage.echoMessage() echoed: I was called from Main app

I notice if I edit the PrintMessage.java file (eg change the output message) I can run the App.java file without recompiling and the change shows up. Cool.

==== Code samples ====

(I deleted the src/test and target folders for clarity)

在此处输入图像描述

The parent pom.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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>

  <name>The Parent project for my test multi modules</name>

  <groupId>com.flowt.multitest</groupId>
  <artifactId>parent</artifactId>
  <version>1.0.0-SNAPSHOT</version>

  <packaging>pom</packaging>

  <modules>
    <module>shared</module>
    <module>mainapp</module>
  </modules>

  <dependencies>

    <!-- The rest of this file is as normal ... -->

The shared pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>

  <!-- Refer to the parent pom.xml -->
  <parent>
    <groupId>com.flowt.multitest</groupId>
    <artifactId>parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>

  <!--
    Since we have a parent we leave this out
    because it is pulled from the parent pom.xml

    <groupId>com.flowt.shared</groupId>
  -->
  <artifactId>shared</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <!-- The rest of this file is as normal ... -->

The mainapp pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>

  <!-- Refer to the parent pom.xml -->
  <parent>
    <groupId>com.flowt.multitest</groupId>
    <artifactId>parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>

  <artifactId>mainapp</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>
      1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <!-- Here you must include the shared project as a dependency -->
    <dependency>
      <groupId>com.flowt.multitest</groupId>
      <artifactId>shared</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

  </dependencies>

  <!-- The rest of this file is as normal ... -->

PrintMessage.java

package com.flowt.messaging;

public class PrintMessage {
  public String echoMessage(String msg) {
    return "PrintMessage.echoMessage() echoed: " + msg;
  }
}

App.java


package com.flowt.app;

// This class is in the shared project: shared/src/main/java/com/flowt/messaging/PrintMessage.java
import com.flowt.messaging.PrintMessage;

/**
 * Hello world!
 */
public class App {
    public static void main( String[] args ) {
        System.out.println( "Hello World!" );

        // The shared class
        PrintMessage printMessage= new PrintMessage();
        String echo = printMessage.echoMessage("I was called from Main app");
        System.out.println(echo);
    }
}

I hope that helps and any expert advice on structuring an app is most welcome.

Go well, Murray

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM