67

I have to copy classpath resource from one package to another.

My program is:

    public static void main(String[] args) throws IOException, URISyntaxException {

            ClassLoader classLoader = CopyFileToDirectoryTest.class.getClassLoader();
InputStream in = classLoader.getResourceAsStream("com/stackoverflow/main/Movie.class");

            URI uri = ClassLoader.getSystemResource("com/stackoverflow/json").toURI();
            Path path = Paths.get(uri.getPath(),"Movie.class");
            System.out.println(path);

            long copy = Files.copy(in, path, StandardCopyOption.REPLACE_EXISTING);
            System.out.println(copy);

        }

At Files.copy method I get exception:

Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <:> at index 2: /D:/Programs/workspaceEE/HibernateDemo/target/classes/com/stackoverflow/json
    at sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
    at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
    at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
    at sun.nio.fs.WindowsPath.parse(WindowsPath.java:94)
    at sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:255)
    at java.nio.file.Paths.get(Paths.java:84)
    at com.stackoverflow.main.CopyFileToDirectoryTest.main(CopyFileToDirectoryTest.java:34)

How to solve it?

Solution

public static void main(String[] args) throws IOException, URISyntaxException {
        ClassLoader classLoader = CopyFileToDirectoryTest.class.getClassLoader();
        InputStream in = classLoader.getResourceAsStream("com//stackoverflow//main//Movie.class");
        URI uri = ClassLoader.getSystemResource("com//stackoverflow//json").toURI();
        String mainPath = Paths.get(uri).toString();
        Path path = Paths.get(mainPath, "Movie.class");
        System.out.println(path);
        long copy = Files.copy(in, path, StandardCopyOption.REPLACE_EXISTING);
        System.out.println(copy);
    }

This code correctly copies Movie.class from package com/stackoverflow/main into com/stackoverflow/json.

4
  • 2
    This doesn't work because your classpath is composed of transparent and opaque resources - such as those inside a jar. You are trying to write to a path that looks something like jar:file:/com/stackoverflow/json, which is an invalid Path or File but a valid URI. In general, you cannot write to the classpath, only read from it. Commented May 15, 2017 at 6:47
  • No jar it is maven project Commented May 15, 2017 at 6:49
  • When you compile a Maven project it will generate a jar. How else would you distribute your compiled code? (Pre Java 9 that is) Commented May 15, 2017 at 6:50
  • Does this answer your question? Java NIO file path issue Commented Nov 14, 2019 at 11:00

10 Answers 10

77

problem is that Paths.get() doesn't expect that kind of value which is generated from uri.getPath().

Solution:

URI uri = ClassLoader.getSystemResource("com/stackoverflow/json").toURI();
String mainPath = Paths.get(uri).toString();
Path path = Paths.get(mainPath ,"Movie.class");
Sign up to request clarification or add additional context in comments.

Comments

11

Try this:

Path path = new File(getClass()
.getResource("/<path to the image in your build/classes folder>")
.getFile()).toPath();

to get the correct path. Worked for me after several hours trying to find out why I couldn't get the file from the jar. This works for NetBeans 8.02

Comments

5

I had the same issue and got the exception, noticed there was a space in the filename, so I had to trim it. After that, the issue is resolved.

Path filePath = Paths.get(dirPathStr, newFileName.trim());

Comments

4

After trying many times, this worked for me

      Path path = new File(getClass().getResource("/data.json").getFile()).toPath(); 

Now you can use your path as you wish e.g

        Reader reader = Files.newBufferedReader(path);

Comments

2

I have the same problem which I was facing from the past two days and finally, I got it Space causes such problem try to solve

var fileName=YourFileName.trim();
Path filePath = Paths.get(dirPathStr, fileName);

Comments

1

I had the same error

./gradlew build

2023-04-10T16:56:54.855+02:00 INFO 10476 --- [ main] c.v.s.d.m.a.VogellaApplication : No active profile set, falling back to 1 default profile: "default" Exception in thread "main" java.nio.file.InvalidPathException: Trailing char < > at index 27: com.vogella.spring.di.model at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:191) at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153) at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77) at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)

I analyzed the filenames and the configuration. I noticed a space in the 'group' property in build.gradle file

group = 'com.vogella.spring.di.model '

I removed the extra space and the build command worked fine.

Comments

0

The following solutions work correctly:

Solution1:

String logFileLocalPath = "../log/log.txt";
File logFile = new File(getURL(logFileLocalPath).getPath());

Solution 2:

File logFile = new 
File(Paths.get(getURL(logFileLocalPath).toURI()).toString());

private static URL getURL(String localPath) {

      return Main.class.getResource(localPath);
}

Comments

0

I faced same issue while using extentReports in my automation, i simply corrected the report path

public void config() {
    String path = System.getProperty("user.dir")+"\\reports\\index.html";       
    ExtentSparkReporter reporter = new ExtentSparkReporter(path);
    reporter.config().setReportName("Web Automation Reports");
    reporter.config().setDocumentTitle("Web Results");

... }

Comments

0
I faced this issue while working on microservices application

package com.test.employeeapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients(basePackages = "com.test.employeeapp.feignclient ")
public class EmployeeServiceApplication {

public static void main(String[] args) {
    SpringApplication.run(EmployeeServiceApplication.class, args);
}

}
in basePackages where have by mistake placed one extra space I just removed it 
and it worked
so what I suggest that just cross check once any extra space is added. 

Comments

0

I want to contribute with one possible solution. First of all, the origin of the problem is because of the structure of the path. Working with Windows is different from Mac and Linux.

  • In linux the path will never contain ":" char.
  • In windows the path always start with capital letter (D:, C:, etc) and not with "/" like Linux or Mac.

Try removing the first "/" that is before the capital letter, like this:

URI uri = ClassLoader.getSystemResource("com/stackoverflow/json").toURI();// "/D:/Programs/workspaceEE/HibernateDemo/target/classes/com/stackoverflow/json"
String uriPath = uri.getPath();
return Paths.get(uriPath.substring(1));// "D:/Programs/workspaceEE/HibernateDemo/target/classes/com/stackoverflow/json"

Remember, this works fine only for Windows OS.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.