2008-09-20 11 views
5

मेरे पास एक जावा प्रोग्राम है जो तृतीय पक्ष वर्ग फ़ाइलों को लोड करता है (कक्षाएं जिन्हें मैंने नहीं लिखा था) और उन्हें निष्पादित करता है। ये कक्षाएं अक्सर java.util.Random का उपयोग करती हैं, जो डिफ़ॉल्ट रूप से यादृच्छिक प्रारंभिक बीज मान उत्पन्न करती है जब भी यह तत्काल हो जाती है। पुनरुत्पादन के कारणों के लिए, मैं इन कक्षाओं को हर बार एक ही प्रारंभिक बीज देना चाहता हूं, इसे केवल अपने विवेकानुसार बदलना चाहता हूं।मैं java.util.Random को तृतीय पक्ष वर्गों में एक विशिष्ट बीज कैसे दे सकता हूं?

यहाँ स्पष्ट समाधान में से कुछ हैं, और क्यों वे काम नहीं करते:

  1. तीसरे पक्ष classfiles में एक अलग यादृच्छिक वर्ग का प्रयोग करें। यहां समस्या यह है कि मैं केवल वर्ग फ़ाइलों को लोड करता हूं, और स्रोत को संशोधित नहीं कर सकता।

  2. JVM के संस्करण की बजाय अपनी खुद की यादृच्छिक कक्षा लोड करने के लिए कस्टम क्लासलोडर का उपयोग करें। यह दृष्टिकोण काम नहीं करेगा क्योंकि जावा क्लासलोडर्स को java पैकेज में कक्षाओं को ओवरराइड करने की अनुमति नहीं देता है।

  3. rt.jar के java.util.Random कार्यान्वयन को स्वयं के लिए कार्यान्वित करें, या फ़ाइलों को JVM के लिए विश्वसनीय स्थानों में डालें। इन दृष्टिकोणों को उनके मशीन पर जेवीएम इंस्टॉल के साथ एप्लिकेशन मैसेजिंग के उपयोगकर्ता की आवश्यकता होती है, और कोई अच्छा नहीं है।

  4. बूटक्लासपैथ में एक कस्टम java.util.Random कक्षा जोड़ना। हालांकि यह तकनीकी रूप से काम करेगा, इस विशेष आवेदन के लिए, यह अव्यवहारिक है क्योंकि यह एप्लिकेशन अंतिम उपयोगकर्ताओं को आईडीई से चलाने के लिए है। मैं ऐप को उपयोगकर्ताओं के लिए सुविधाजनक बनाना चाहता हूं, जिसका अर्थ है कि उन्हें बूटक्लासपैथ सेट करने के लिए मजबूर करना एक दर्द है। मैं एक स्क्रिप्ट में इस छिपा कर सकते हैं नहीं है, क्योंकि यह ग्रहण की तरह एक IDE से चलाया जा करने का इरादा है (आसान डिबगिंग के लिए।)

तो मैं यह कैसे कर सकते हैं?

उत्तर

2

तीसरे पक्ष के पुस्तकालयों को संशोधित करने पर विचार करें ताकि उन्हें उनके यादृच्छिक उदाहरणों के लिए देखा जा सके। यद्यपि आपके पास स्रोत कोड नहीं है, लेकिन आप इसे करने के लिए बाइटकोड संपादित कर सकते हैं। ऐसा करने के लिए एक उपयोगी टूलकिट ASM है। निर्मित दो ThirdPartyClass.java और Random.java

बनाया जार नामित परीक्षण के लिए कक्षाएं ThirdPartyClass.class

jar -cvf tpc.jar ThirdPartyClass.class 

बनाया जार से से Random.class

jar -cvf rt123.jar Random.class 

कि अमल के बाद:

1

आप एओपी का उपयोग यादृच्छिक रूप से कॉल को रोकने के लिए कर सकते हैं और जो चाहते हैं उसे तर्क को घुमा सकते हैं।

सैम

0

"JVM के संस्करण के बजाय अपने स्वयं के यादृच्छिक वर्ग लोड करने के लिए एक कस्टम classloader का प्रयोग करें। यह दृष्टिकोण काम नहीं करेगा क्योंकि जावा classloaders जावा पैकेज में कक्षाएं ओवरराइड करने की अनुमति नहीं है।"

अपने कस्टम रैंडम क्लास का उपयोग करने के लिए बूटक्लासपैथ को बदलने के बारे में कैसे?

बीआर, ~ एक

+0

चा बूटक्लासपैज को नजदीक करना प्रभावी है, लेकिन जावा प्रोग्राम चलाने के तरीके को संशोधित करने की आवश्यकता है। यह ठीक है अगर आप किसी प्रोग्राम को लॉन्च करने के तरीके को नियंत्रित कर सकते हैं, उदा। एक स्टार्टअप स्क्रिप्ट, लेकिन मेरे मामले में उपयोगकर्ता आमतौर पर एक आईडीई के भीतर से भागते हैं और इसे मैन्युअल रूप से करना होगा, जो कि अच्छा नहीं है। – adum

1

यद्यपि आप तुच्छता "java.x" और "sun.x" पैकेज के लिए classloader नहीं बदल सकते हैं, वहाँ वर्ग लोड हो रहा है लगता है (और एक "कक्षा के बाद स्थापित करने के लिए एक रास्ता है थीस वर्गों के बाइटकोड और लोड "श्रोता) थे, ताकि आप इन पैकेजों से कक्षाओं को लोड करने के बाद बीज की तरह कुछ सेट कर सकें। संकेत: प्रतिबिंब का प्रयोग करें।

वैसे भी, जब तक मेरे पास और जानकारी नहीं है कि आप वास्तव में क्या हासिल करना चाहते हैं, तो यहां आपकी सहायता करना बहुत मुश्किल है।

पीएस .: जागरूक रहें कि "स्थैतिक {}" - ब्लॉक आपको बीज के साथ फिर से गड़बड़ कर सकते हैं।

3

आपका विकल्प 2 वास्तव में निम्न दिशाओं के साथ काम करेगा।

बूटस्ट्रैप क्लास पथ बदलने के लिए आपको (जैसा कि पंजाब ने कहा) की आवश्यकता होगी।

कार्यक्रम आप निम्नलिखित जोड़ने की जरूरत के कमांड लाइन में: C:

जावा -Xbootclasspath/p \ अपने \ random_impl.jar YourProgram

मान लिया जाये कि आप windown मशीन या पर हैं किसी भी ओएस में उस मामले के लिए पथ।

वह विकल्प rt.jar लोड होने से पहले जार फ़ाइलों में कक्षाओं को जोड़ता है। तो आपका रैंडम आरटी.जर रैंडम क्लास से पहले लोड हो जाएगा।

उपयोग टाइप करके प्रदर्शित होता है:

java -X 

यह सब एक्स (tra) को प्रदर्शित करता है सुविधाएँ डे JVM है। यह अन्य वीएम कार्यान्वयन जैसे जेआरॉकिट या अन्य पर उपलब्ध नहीं हो सकता है लेकिन यह सूर्य जेवीएम पर है।

-Xbootclasspath/p: बूटस्ट्रैप वर्ग पथ के सामने आगे जोड़ते

मैं एक आवेदन जहां डिफ़ॉल्ट ओर्ब वर्ग अन्य लोगों के साथ प्रतिस्थापित किया जाना चाहिए में इस दृष्टिकोण का उपयोग किया है कार्यान्वयन ओर्ब। ओआरबी कक्षा जावा कोर का हिस्सा है और कभी भी कोई समस्या नहीं थी।

शुभकामनाएं।

0

हां विकल्प 2 काम कर रहा है निम्नलिखित कमांड के साथ:

java -Xbootclasspath/p:tcp.jar:rt123.jar -cp . -verbose ThirdPartyClass 

उत्पादन होगा: seed value for ThirdPartyClass-> 1

स्रोत कोड ThirdPartyClass.java ----->

import java.util.Random; 

public class ThirdPartyClass { 
    ThirdPartyClass(long seed) { 
     System.out.println("seed value for ThirdPartyClass-> "+seed); 
    } 

    public static void main(String [] args) { 
     ThirdPartyClass tpc=new ThirdPartyClass(new Random().nextLong()); 
    } 
} 

स्रोत कोड Random.java ------->

package java.util; 

import java.io.Serializable; 

public class Random extends Object implements Serializable 
{ 
    public Random() { 
    } 

    public Random(long seed) { 
    } 

    public long nextLong() { 
     return 1; 
    } 
} 

धन्यवाद महावीर प्रसाद माली

संबंधित मुद्दे