জার হিসাবে চলার সময় ক্লাসপাথ সংস্থান খুঁজে পাওয়া যায় নি


127

স্প্রিং বুট ১.১.৫ এবং ১.১. this উভয় ক্ষেত্রেই এই সমস্যাটি রয়েছে - আমি @ ভ্যালু টিকাটি ব্যবহার করে একটি ক্লাসপাথ সংস্থান লোড করছি, যা এসটিএসের মধ্যে অ্যাপ্লিকেশন চালানোর সময় ঠিক কাজ করে (3.6.0, উইন্ডোজ)। যাইহোক, যখন আমি একটি এমভিএন প্যাকেজ পরিচালনা করি এবং তারপরে জারটি চালানোর চেষ্টা করি, তখন আমি ফাইলনটফাউন্ড ব্যতিক্রম পাই।

রিসোর্স, ম্যাসেজ.টিএসটিএসটি, এসসিআর / মেইন / রিসোর্সে রয়েছে। আমি জারটি পরিদর্শন করেছি এবং যাচাই করেছি যে এটিতে শীর্ষ স্তরে ("অ্যাপ্লিকেশন.পোপার্টি হিসাবে একই স্তরের)" ম্যাসেজ.টেক্সট "ফাইল রয়েছে।

আবেদনটি এখানে:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application implements CommandLineRunner {

    private static final Logger logger = Logger.getLogger(Application.class);

    @Value("${message.file}")
    private Resource messageResource;

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

    @Override
    public void run(String... arg0) throws Exception {
        // both of these work when running as Spring boot app from STS, but
        // fail after mvn package, and then running as java -jar
        testResource(new ClassPathResource("message.txt"));
        testResource(this.messageResource);
    }

    private void testResource(Resource resource) {
        try {
            resource.getFile();
            logger.debug("Found the resource " + resource.getFilename());
        } catch (IOException ex) {
            logger.error(ex.toString());
        }
    }
}

ব্যতিক্রম:

c:\Users\glyoder\Documents\workspace-sts-3.5.1.RELEASE\classpath-resource-proble
m\target>java -jar demo-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.1.5.RELEASE)

2014-09-16 08:46:34.635  INFO 5976 --- [           main] demo.Application
                  : Starting Application on 8W59XV1 with PID 5976 (C:\Users\glyo
der\Documents\workspace-sts-3.5.1.RELEASE\classpath-resource-problem\target\demo
-0.0.1-SNAPSHOT.jar started by glyoder in c:\Users\glyoder\Documents\workspace-s
ts-3.5.1.RELEASE\classpath-resource-problem\target)
2014-09-16 08:46:34.640 DEBUG 5976 --- [           main] demo.Application
                  : Running with Spring Boot v1.1.5.RELEASE, Spring v4.0.6.RELEA
SE
2014-09-16 08:46:34.681  INFO 5976 --- [           main] s.c.a.AnnotationConfigA
pplicationContext : Refreshing org.springframework.context.annotation.Annotation
ConfigApplicationContext@1c77b086: startup date [Tue Sep 16 08:46:34 EDT 2014];
root of context hierarchy
2014-09-16 08:46:35.196  INFO 5976 --- [           main] o.s.j.e.a.AnnotationMBe
anExporter        : Registering beans for JMX exposure on startup
2014-09-16 08:46:35.210 ERROR 5976 --- [           main] demo.Application
                  : java.io.FileNotFoundException: class path resource [message.
txt] cannot be resolved to absolute file path because it does not reside in the
file system: jar:file:/C:/Users/glyoder/Documents/workspace-sts-3.5.1.RELEASE/cl
asspath-resource-problem/target/demo-0.0.1-SNAPSHOT.jar!/message.txt
2014-09-16 08:46:35.211 ERROR 5976 --- [           main] demo.Application
                  : java.io.FileNotFoundException: class path resource [message.
txt] cannot be resolved to absolute file path because it does not reside in the
file system: jar:file:/C:/Users/glyoder/Documents/workspace-sts-3.5.1.RELEASE/cl
asspath-resource-problem/target/demo-0.0.1-SNAPSHOT.jar!/message.txt
2014-09-16 08:46:35.215  INFO 5976 --- [           main] demo.Application
                  : Started Application in 0.965 seconds (JVM running for 1.435)

2014-09-16 08:46:35.217  INFO 5976 --- [       Thread-2] s.c.a.AnnotationConfigA
pplicationContext : Closing org.springframework.context.annotation.AnnotationCon
figApplicationContext@1c77b086: startup date [Tue Sep 16 08:46:34 EDT 2014]; roo
t of context hierarchy
2014-09-16 08:46:35.218  INFO 5976 --- [       Thread-2] o.s.j.e.a.AnnotationMBe
anExporter        : Unregistering JMX-exposed beans on shutdown

উত্তর:


201

resource.getFile()রিসোর্সটি ফাইল সিস্টেমে উপলব্ধ হওয়ার প্রত্যাশা করে, অর্থাত্ এটি কোনও জার ফাইলের মধ্যে বাসা বাঁধতে পারে না। এই কারণেই আপনি যখন এসটিএসে আপনার অ্যাপ্লিকেশনটি চালাবেন এটি কাজ করে তবে একবার আপনি নিজের অ্যাপ্লিকেশন তৈরি করে এবং এক্সিকিউটেবল জার থেকে চালানোর পরে এটি কাজ করে না। getFile()রিসোর্সের সামগ্রীগুলি অ্যাক্সেস করতে ব্যবহার করার পরিবর্তে , আমি getInputStream()পরিবর্তে ব্যবহার করার পরামর্শ দেব । এটি আপনাকে উত্সের সামগ্রীটি যেখানেই থাকুক না কেন পড়ার অনুমতি দেবে।


6
আমার ক্ষেত্রে, আমাকে কীস্টোর ফাইলের (একটি টমক্যাট https সংযোগকারীর জন্য) একটি পথ সরবরাহ করা প্রয়োজন I উপরের সমাধান অনুযায়ী এটি সম্ভব নয়। আপনি এটি করার অতিরিক্ত উপায়ের সাথে পরিচিত?
মোদি

1
আমার খুব অনুরূপ চাহিদা রয়েছে এবং এমন কোনও অ্যাপস নেই যা আপনাকে জারের অংশ হিসাবে কীস্টোরটি সেট করতে দেয়। @ মোদি, আপনি কি কোনও সমাধান খুঁজে পেতে সক্ষম হয়েছিলেন?
রবিন ভার্গিজ

আপনি কী স্টোর ব্যবহারের ক্ষেত্রে বোঝাতে চান? আপনি কি টমকেট সহ স্প্রিং বুট ব্যবহার করছেন?
মোদী

@ রবিনবার্গিজ আপনার সমস্যার কোনও সমাধান খুঁজে পেয়েছেন। আমারও একই রকম ব্যবহারের কেস সমাধান করতে হবে। আপনার কিছু পরামর্শ থাকলে প্রশংসা করুন।
দিগন্ত 7

যদি টমক্যাটটির জন্য https সক্ষম করতে কীস্টোরের অবস্থান প্রয়োজন হয় তবে কেউ classpath:filenameকীস্টোর ফাইলটি জারের মধ্যে থেকে পড়তে পারে।
দিগন্ত 7

60

আপনি Spring ফ্রেমওয়ার্ক ব্যবহার করছেন, তাহলে পড়া ClassPathResourceএকটি মধ্যে Stringব্যবহার বেশ সহজ স্প্রিং ফ্রেমওয়ার্ক এরFileCopyUtils :

String data = "";
ClassPathResource cpr = new ClassPathResource("static/file.txt");
try {
    byte[] bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream());
    data = new String(bdata, StandardCharsets.UTF_8);
} catch (IOException e) {
    LOG.warn("IOException", e);
}

ফাইলটি কোথায় বসতে হবে সে সম্পর্কে কোনও বাধা আছে? এটা ক্লাসপথে কোথাও হতে পারে? এটা কি প্রকল্পের মূল হতে পারে?
স্টিফেন

এটি ক্লাসপাথের যে কোনও জায়গায় হতে পারে।
অনুভা

45

আপনি যদি কোনও ফাইল ব্যবহার করতে চান:

ClassPathResource classPathResource = new ClassPathResource("static/something.txt");

InputStream inputStream = classPathResource.getInputStream();
File somethingFile = File.createTempFile("test", ".txt");
try {
    FileUtils.copyInputStreamToFile(inputStream, somethingFile);
} finally {
    IOUtils.closeQuietly(inputStream);
}

7

যখন বসন্ত বুট প্রকল্পটি জার হিসাবে চলমান থাকে এবং শ্রেণিপথের কোনও ফাইল পড়তে হবে, আমি কোডের নীচে এটি প্রয়োগ করি

Resource resource = new ClassPathResource("data.sql");
BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
reader.lines().forEach(System.out::println);

3

ক্লাসপাথ থেকে সহজভাবে পড়া ফাইলগুলি তৈরি করার জন্য আমি একটি জাভা 8 উপায়ে একটি ClassPathResourceReader ক্লাস তৈরি করেছি

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

import org.springframework.core.io.ClassPathResource;

public final class ClassPathResourceReader {

    private final String path;

    private String content;

    public ClassPathResourceReader(String path) {
        this.path = path;
    }

    public String getContent() {
        if (content == null) {
            try {
                ClassPathResource resource = new ClassPathResource(path);
                BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
                content = reader.lines().collect(Collectors.joining("\n"));
                reader.close();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
        return content;
    }
}

ইউটিলাইজেশন:

String content = new ClassPathResourceReader("data.sql").getContent();

2

আমিও এই সীমাবদ্ধতার মুখোমুখি হয়েছি এবং সমস্যাটি কাটিয়ে ওঠার জন্য এই লাইব্রেরিটি তৈরি করেছি: স্প্রিং-বুট-জার-রিসোর্সগুলি মূলত আপনাকে স্প্রিং বুটের সাথে একটি কাস্টম রিসোর্সলোডার রেজিস্ট্রেশন করতে দেয় যা প্রয়োজন অনুসারে জার থেকে ক্লাসপাথ সংস্থানগুলি স্বচ্ছভাবে বের করে দেয়।


2
to get list of data from src/main/resources/data folder --
first of all mention your folder location in properties file as - 
resourceLoader.file.location=data

inside class declare your location. 

@Value("${resourceLoader.file.location}")
    @Setter
    private String location;

    private final ResourceLoader resourceLoader;

public void readallfilesfromresources() {
       Resource[] resources;

        try {
            resources = ResourcePatternUtils.getResourcePatternResolver(resourceLoader).getResources("classpath:" + location + "/*.json");
            for (int i = 0; i < resources.length; i++) {
                try {
                InputStream is = resources[i].getInputStream();
                byte[] encoded = IOUtils.toByteArray(is);
                String content = new String(encoded, Charset.forName("UTF-8"));
                }
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
}

1

জার্সির আনপ্যাক করা জারগুলি হওয়া দরকার।

<build>  
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <requiresUnpack>
                    <dependency>
                        <groupId>com.myapp</groupId>
                        <artifactId>rest-api</artifactId>
                    </dependency>
                </requiresUnpack>
            </configuration>
        </plugin>
    </plugins>
</build>  

0
in spring boot :

1) if your file is ouside jar you can use :        

@Autowired
private ResourceLoader resourceLoader;

**.resource(resourceLoader.getResource("file:/path_to_your_file"))**

2) if your file is inside resources of jar you can `enter code here`use :

**.resource(new ClassPathResource("file_name"))**

0

অ্যান্ডির উত্তরের উপর ভিত্তি করে আমি সমস্ত YAML গুলির ইনপুট স্ট্রিমগুলি ডিরেক্টরিতে সংস্থান এবং ডিরেক্টরিগুলির সাব-ডিরেক্টরিগুলির অধীনে পাওয়ার জন্য নিম্নলিখিতটি ব্যবহার করেছি (নোট করুন যে পাসটি শুরু হয়নি /):

private static Stream<InputStream> getInputStreamsFromClasspath(
        String path,
        PathMatchingResourcePatternResolver resolver
) {
    try {
        return Arrays.stream(resolver.getResources("/" + path + "/**/*.yaml"))
                .filter(Resource::exists)
                .map(resource -> {
                    try {
                        return resource.getInputStream();
                    } catch (IOException e) {
                        return null;
                    }
                })
                .filter(Objects::nonNull);
    } catch (IOException e) {
        logger.error("Failed to get definitions from directory {}", path, e);
        return Stream.of();
    }
}

0

আমি অনুরূপ সিটেটেশনতেও জড়িত হয়েছি কিন্তু একেবারে অনুরূপ নয়, উত্স ফোল্ডার থেকে একটি জেএসওএন ফাইলটি পড়তে চেয়েছিলাম।সিআরসি / প্রধান / সংস্থানসমূহ সুতরাং নীচে এই জাতীয় কিছু লেখা হয়েছিল written

একটি ফাইল পড়ার জন্য এখানে বিভিন্ন উপায় তালিকাভুক্ত করা হয়েছেস্প্রিং বুট অ্যাপ্লিকেশনটিতে রোম ক্লাসপথ ।

@ ভ্যালু ("শ্রেণীপথ: টেস্ট.জসন") ব্যক্তিগত রিসোর্স সংস্থান;

File file = resource.getFile();

@Value("classpath:test.json")

ব্যক্তিগত সম্পদ সংস্থান;

File file = resource.getFile();

এখন, এই কোডটি এমভিএন: স্প্রিং-বুট: রান ব্যবহার করে চালানোর পরে এই কোডটি পুরোপুরি সূক্ষ্মভাবে কাজ করে soon আসুন এখন এগিয়ে যান এবং এখনই সমাধানটি সন্ধান করুন।

ইনপুট স্ট্রিম ব্যবহার করা আমার ক্ষেত্রে আমার উত্তরটি খুঁজে পেয়েছিল: -

@Value("classpath:test.json")
    Resource resourceFile;

private void testResource(Resource resource) {
        try {
            InputStream resourcee = resource.getInputStream();
            String text = null;
            try (final Reader reader = new InputStreamReader(resourcee)) {
                text = CharStreams.toString(reader);
            }
            System.out.println(text);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

ফ্রি জার কনসেপ্টে স্প্রিং কাজ করে, সুতরাং এটি গ্রহস্বরে ভিন্নভাবে আচরণ করে এবং আপনি যখন জার হিসাবে চালাচ্ছেন তখন এটি সত্যই জটিল।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.