Tôi đang sử dụng một số mã của bên thứ ba mà khi đưa ra một đối số dòng lệnh '-classpath' không thiết lập java.class.path, nhưng thay vì chỉ tạo một trình nạp lớp, hãy thêm tất cả các url cho các mục trên dòng lệnh được chỉ định classpath trình nạp lớp, và sau đó đặt nó làm trình nạp lớp ngữ cảnh. Trong một lớp plugin cho mã này mà tôi đã viết, tôi nhận được một thể hiện của trình nạp lớp này, và bằng cách nào đó cần sử dụng nó để lấy lại đường dẫn lớp cơ sở, để tôi có thể sử dụng nó trong một lời gọi của JavaCompiler.getTask (.. .) và biên dịch một số mã khác trên bay. Tuy nhiên có vẻ như không có anyway để có được ClassPath từ ClassLoader, và như java.class.path là unset, tôi dường như không thể truy cập classpath cơ bản mà ứng dụng ban đầu được gọi với ... ?Làm thế nào để có được classpath từ classloader?
Trả lời
Nếu trình nạp lớp sử dụng URL, nó phải là URLClassloader
. Những gì bạn có quyền truy cập là các URL xác định đường dẫn lớp học cho nó cùng với phụ huynh ClassLoader
.
Để có được URL, bạn chỉ cần làm như sau:
((URLClassLoader) (Thread.currentThread().getContextClassLoader())).getURLs()
Để tham khảo trong tương lai, trong trường hợp bạn cần phải vượt qua trong đường dẫn lớp để ProcessBuilder
:
StringBuffer buffer = new StringBuffer();
for (URL url :
((URLClassLoader) (Thread.currentThread()
.getContextClassLoader())).getURLs()) {
buffer.append(new File(url.getPath()));
buffer.append(System.getProperty("path.separator"));
}
String classpath = buffer.toString();
int toIndex = classpath
.lastIndexOf(System.getProperty("path.separator"));
classpath = classpath.substring(0, toIndex);
ProcessBuilder builder = new ProcessBuilder("java",
"-classpath", classpath, "com.a.b.c.TestProgram");
Trong trường hợp câu trả lời khác don Không hoạt động, hãy thử cách này:
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader) cl).getURLs();
for (URL url: urls) {
System.out.println(url.getFile());
}
Các câu trả lời khác là đúng trong hầu hết các trường hợp, nhưng nó trở nên phức tạp hơn trong một số cài đặt: ví dụ: Maven, Tomcat và JUnit có hỗ trợ classpath riêng của họ và họ không sử dụng classpath hệ thống.
Cho đến nay đây là hệ thống hoàn chỉnh nhất mà tôi đã quản lý để đưa ra (mã này là từ dự án Fast Classpath Scanner của tôi):
/** The unique elements of the classpath, as an ordered list. */
private final ArrayList<File> classpathElements = new ArrayList<>();
/** The unique elements of the classpath, as a set. */
private final HashSet<String> classpathElementsSet = new HashSet<>();
/** Clear the classpath. */
private void clearClasspath() {
classpathElements.clear();
classpathElementsSet.clear();
}
/** Add a classpath element. */
private void addClasspathElement(String pathElement) {
if (classpathElementsSet.add(pathElement)) {
final File file = new File(pathElement);
if (file.exists()) {
classpathElements.add(file);
}
}
}
/** Parse the system classpath. */
private void parseSystemClasspath() {
// Look for all unique classloaders.
// Keep them in an order that (hopefully) reflects the order in which class resolution occurs.
ArrayList<ClassLoader> classLoaders = new ArrayList<>();
HashSet<ClassLoader> classLoadersSet = new HashSet<>();
classLoadersSet.add(ClassLoader.getSystemClassLoader());
classLoaders.add(ClassLoader.getSystemClassLoader());
if (classLoadersSet.add(Thread.currentThread().getContextClassLoader())) {
classLoaders.add(Thread.currentThread().getContextClassLoader());
}
// Dirty method for looking for any other classloaders on the call stack
try {
// Generate stacktrace
throw new Exception();
} catch (Exception e) {
StackTraceElement[] stacktrace = e.getStackTrace();
for (StackTraceElement elt : stacktrace) {
try {
ClassLoader cl = Class.forName(elt.getClassName()).getClassLoader();
if (classLoadersSet.add(cl)) {
classLoaders.add(cl);
}
} catch (ClassNotFoundException e1) {
}
}
}
// Get file paths for URLs of each classloader.
clearClasspath();
for (ClassLoader cl : classLoaders) {
if (cl != null) {
for (URL url : ((URLClassLoader) cl).getURLs()) {
if ("file".equals(url.getProtocol())) {
addClasspathElement(url.getFile());
}
}
}
}
}
/** Override the system classpath with a custom classpath to search. */
public FastClasspathScanner overrideClasspath(String classpath) {
clearClasspath();
for (String pathElement : classpath.split(File.pathSeparator)) {
addClasspathElement(pathElement);
}
return this;
}
/**
* Get a list of unique elements on the classpath (directories and files) as File objects, preserving order.
* Classpath elements that do not exist are not included in the list.
*/
public ArrayList<File> getUniqueClasspathElements() {
return classpathElements;
}
Chắc chắn câu trả lời hoàn chỉnh nhất và tích cực phát triển nếu bạn làm theo dự án. –
Phương pháp bẩn đó tìm kiếm bất kỳ trình nạp lớp khác trên ngăn xếp cuộc gọi chính xác là những gì tôi cần! Cám ơn rất nhiều! – FelipeKunzler
@ luke-hutchison thư viện của bạn là một người tiết kiệm cuộc sống! Đối với bất cứ ai muốn một giải pháp mà được classpath cho một loạt các môi trường thời gian chạy này là tốt nhất hiện có. – Dan
Drop mã này vào một trang jsp trống để xem hệ thống phân cấp classloader và liên kết lọ được nạp ở mỗi cấp.
lần() phương pháp dưới đây có thể cũng được sử dụng ngày của riêng mình
<%!
public void visit(StringBuilder sb, int indent, ClassLoader classLoader) {
if (indent > 20 || classLoader == null)
return;
String indentStr = new String(new char[indent]).replace("\0", " ");
sb.append("\n");
sb.append(indentStr);
sb.append(classLoader.getClass().getName());
sb.append(":");
if (classLoader instanceof java.net.URLClassLoader) {
java.net.URL[] urls = ((java.net.URLClassLoader)classLoader).getURLs();
for (java.net.URL url : urls) {
sb.append("\n");
sb.append(indentStr);
sb.append(url);
}
}
sb.append("\n");
visit(sb, indent + 1, classLoader.getParent());
}
%>
<%
StringBuilder sb = new StringBuilder();
visit(sb,1,this.getClass().getClassLoader());
%>
<pre>
<%=sb%>
</pre>
- 1. Làm thế nào để cấu hình JBOSS 5.1.0 GA ClassLoader
- 2. thêm một thư mục tương ứng với java classpath và sử dụng ClassLoader(). GetResourceAsStream ("")
- 3. Làm thế nào để thiết lập classpath khi chạy bình làm từ 'lein uberjar'?
- 4. Làm thế nào để sửa đổi classpath trong Eclipse?
- 5. Làm thế nào để có được char ép từ System.Windows.Input.KeyEventArgs?
- 6. Làm thế nào để có được dụ từ Ninject
- 7. làm thế nào để có được văn bản từ TextView
- 8. C# làm thế nào để có được Byte [] từ IntPtr
- 9. Làm thế nào để có được đầu ra từ subprocess.Popen()
- 10. Làm thế nào để có được subarray từ mảng?
- 11. Làm thế nào để có được Backbone.Collection từ Backbone.LocalStorage
- 12. ClassLoader getResourceAsStream trả về null
- 13. Classpath cho plugin kiến khi sử dụng ANTBuilder từ Gradle
- 14. Java ClassLoader thay đổi
- 15. ClassPathResource không nhận được classpath
- 16. Làm cách nào để đặt classpath mà rmiregistry sử dụng?
- 17. Làm thế nào để có được giá trị lớn nhất từ NSArray có chứa từ điển?
- 18. Làm cách nào để kiểm soát ClassLoader nào sẽ tải lớp học?
- 19. Làm thế nào để có được php_phar.dll?
- 20. Làm thế nào tôi có thể có một phụ thuộc Maven trên classpath thời gian chạy nhưng không phải là classpath thử nghiệm?
- 21. Làm thế nào để có được trạng thái hoàn thành chương trình java từ tập lệnh shell unix?
- 22. Ví dụ Java với ClassLoader
- 23. Làm thế nào để đặt một lọ trong classpath trong Eclipse?
- 24. Làm thế nào để tôi có thể làm cho maven xây dựng thêm tài nguyên cho classpath?
- 25. Đang tải các tập tin với ClassLoader
- 26. Làm thế nào để cấu hình classpath eclipse được sử dụng cho các bài kiểm tra junit?
- 27. Cách tải hình ảnh cho Android ImageView từ classpath?
- 28. Hiểu tờ khai classpath Eclipse
- 29. User Defined ClassLoader Trong C#
- 30. định vị tập tin trong một classpath
Làm việc, nhờ :) –
Bạn đang chào đón! –