জাভা থেকে ক্লোজার ডাকছে


165

"জাভা থেকে ক্লোজার কল করার জন্য" শীর্ষস্থানীয় গুগল হিটগুলির বেশিরভাগ পুরানো এবং clojure.lang.RTউত্স কোডটি সংকলন করার জন্য ব্যবহারের পরামর্শ দেয় । আপনি ইতিমধ্যে ক্লোজার প্রকল্প থেকে একটি জার তৈরি করেছেন এবং ক্লাসপথে অন্তর্ভুক্ত করেছেন এই ধারণা করে কীভাবে জাভা থেকে ক্লোজারকে কল করবেন তার স্পষ্ট ব্যাখ্যা দিয়ে আপনি সহায়তা করতে পারেন?


8
আমি জানি না যে উত্সটি প্রতিটি সময় সংকলন করা যেমন "পুরানো" হয়। এটি একটি ডিজাইনের সিদ্ধান্ত। এটি এখনই করছি যখন এটি ক্লোজার কোডটি একটি উত্তরাধিকারী জাভা নেটবিয়ান প্রকল্পে স্ন্যাপ হিসাবে সংহত করে। ক্লোজারকে লাইব্রেরি হিসাবে যুক্ত করুন, একাধিক সংকলন / লিঙ্কিং পদক্ষেপ ছাড়াই ক্লোজার সোর্স ফাইল যুক্ত করুন, কল সেটআপ করুন এবং তাত্ক্ষণিক ক্লোজার সমর্থন যুক্ত করুন! প্রতিটি অ্যাপ্লিকেশনটিতে দ্বিতীয় বিলম্বের একটি ভগ্নাংশের মূল্যে।
ব্রায়ান নোব্লাচ


2
Clojure 1.8.0 এর জন্য সর্বশেষ দেখুন - ক্লোজুরে এখন সরাসরি সংযোগ রয়েছে।
TWR কোল

উত্তর:


166

আপডেট : যেহেতু এই উত্তরটি পোস্ট করা হয়েছিল, তাই উপলব্ধ কিছু সরঞ্জাম পরিবর্তিত হয়েছে। মূল উত্তরের পরে, বর্তমান সরঞ্জামগুলির সাহায্যে উদাহরণ কীভাবে তৈরি করবেন সে সম্পর্কে তথ্য সহ একটি আপডেট রয়েছে।

এটি কোনও জারকে সংকলন করা এবং অভ্যন্তরীণ পদ্ধতিগুলি কল করার মতো সহজ নয়। যদিও এটি সমস্ত কাজ করার জন্য কয়েকটি কৌশল আছে। এখানে একটি সাধারণ ক্লোজার ফাইলের একটি উদাহরণ যা একটি জারে সংকলন করা যায়:

(ns com.domain.tiny
  (:gen-class
    :name com.domain.tiny
    :methods [#^{:static true} [binomial [int int] double]]))

(defn binomial
  "Calculate the binomial coefficient."
  [n k]
  (let [a (inc n)]
    (loop [b 1
           c 1]
      (if (> b k)
        c
        (recur (inc b) (* (/ (- a b) b) c))))))

(defn -binomial
  "A Java-callable wrapper around the 'binomial' function."
  [n k]
  (binomial n k))

(defn -main []
  (println (str "(binomial 5 3): " (binomial 5 3)))
  (println (str "(binomial 10042 111): " (binomial 10042 111)))
)

আপনি যদি এটি চালনা করেন তবে আপনার এমন কিছু দেখতে পাওয়া উচিত:

(binomial 5 3): 10
(binomial 10042 111): 49068389575068144946633777...

এবং এখানে একটি জাভা প্রোগ্রাম যা -binomialফাংশনটিকে কল করে tiny.jar

import com.domain.tiny;

public class Main {

    public static void main(String[] args) {
        System.out.println("(binomial 5 3): " + tiny.binomial(5, 3));
        System.out.println("(binomial 10042, 111): " + tiny.binomial(10042, 111));
    }
}

এটির ফলাফল:

(binomial 5 3): 10.0
(binomial 10042, 111): 4.9068389575068143E263

জাদুটির প্রথম অংশটি বিবৃতিতে :methodsকীওয়ার্ডটি ব্যবহার করছে gen-class। জাভাতে স্থির পদ্ধতির মতো ক্লোজার ফাংশনটি অ্যাক্সেস করতে আপনাকে এটি আবশ্যক বলে মনে হচ্ছে।

দ্বিতীয় জিনিসটি একটি মোড়ক ফাংশন তৈরি করা যা জাভা দ্বারা কল করা যেতে পারে। লক্ষ্য করুন যে এর দ্বিতীয় সংস্করণটির -binomialসামনে একটি ড্যাশ রয়েছে।

এবং অবশ্যই ক্লোজুর জারটি নিজেই বর্গ পথে চলতে হবে। এই উদাহরণটি Clojure-1.1.0 জার ব্যবহার করেছে।

আপডেট : নিম্নলিখিত উত্তরগুলি ব্যবহার করে এই উত্তরটি পুনরায় পরীক্ষা করা হয়েছে:

  • বন্ধ
  • লিনিঙ্গেন ২.১.৩
  • জেডিকে 1.7.0 আপডেট 25

ক্লোজার পার্ট

প্রথমে লিনিনজেন ব্যবহার করে একটি প্রকল্প এবং সম্পর্কিত ডিরেক্টরি কাঠামো তৈরি করুন:

C:\projects>lein new com.domain.tiny

এখন, প্রকল্প ডিরেক্টরিতে পরিবর্তন করুন।

C:\projects>cd com.domain.tiny

প্রকল্প ডিরেক্টরিতে project.cljফাইলটি খুলুন এবং এটিকে সম্পাদনা করুন যাতে বিষয়বস্তুগুলি নীচে প্রদর্শিত হবে।

(defproject com.domain.tiny "0.1.0-SNAPSHOT"
  :description "An example of stand alone Clojure-Java interop"
  :url "http://clarkonium.net/2013/06/java-clojure-interop-an-update/"
  :license {:name "Eclipse Public License"
  :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.5.1"]]
  :aot :all
  :main com.domain.tiny)

এখন, নিশ্চিত হয়ে নিন যে সমস্ত নির্ভরতা (ক্লোজার) উপলব্ধ।

C:\projects\com.domain.tiny>lein deps

আপনি এই মুহুর্তে ক্লোজার জারটি ডাউনলোড করার বিষয়ে একটি বার্তা দেখতে পাবেন।

এখন ক্লোজার ফাইলটি C:\projects\com.domain.tiny\src\com\domain\tiny.cljএমনভাবে সম্পাদনা করুন যাতে এটির মূল উত্তরে প্রদর্শিত ক্লোজার প্রোগ্রাম রয়েছে। (এই ফাইলটি তৈরি করা হয়েছিল যখন লেনিনজেন প্রকল্পটি তৈরি করেছিলেন))

এখানে বেশিরভাগ যাদু নেমস্পেসের ঘোষণায় রয়েছে। :gen-classএকটি বর্গ নামে তৈরি করতে সিস্টেম বলে com.domain.tinyনামক একটি একক স্থির পদ্ধতি সঙ্গে binomial, একটি ফাংশন দুই পূর্ণসংখ্যা আর্গুমেন্ট গ্রহণ এবং একটি ডবল ফিরিয়ে আনে। দুটি অনুরূপ নামের ফাংশন রয়েছে binomial, একটি aতিহ্যবাহী ক্লোজার ফাংশন এবং -binomialজাভা থেকে অ্যাক্সেসযোগ্য মোড়ক। ফাংশনের নামে হাইফেনটি নোট করুন -binomial। ডিফল্ট উপসর্গটি একটি হাইফেন, তবে এটি যদি ইচ্ছা হয় তবে এটি অন্য কোনও কিছুতে পরিবর্তন করা যায়। -mainআমরা সঠিক ফলাফল পাচ্ছি তা নিশ্চিত করার জন্য ফাংশনটি দ্বিপদী ফাংশনে কেবল কয়েকটি কল করে। এটি করার জন্য, ক্লাসটি সংকলন করুন এবং প্রোগ্রামটি চালান।

C:\projects\com.domain.tiny>lein run

আপনার আসল উত্তরে দেখানো আউটপুট দেখতে হবে।

এখন এটি একটি পাত্রে প্যাকেজ করুন এবং এটি কোথাও সুবিধাজনক রাখুন। ক্লোজারের জারটিও সেখানে অনুলিপি করুন।

C:\projects\com.domain.tiny>lein jar
Created C:\projects\com.domain.tiny\target\com.domain.tiny-0.1.0-SNAPSHOT.jar
C:\projects\com.domain.tiny>mkdir \target\lib

C:\projects\com.domain.tiny>copy target\com.domain.tiny-0.1.0-SNAPSHOT.jar target\lib\
        1 file(s) copied.

C:\projects\com.domain.tiny>copy "C:<path to clojure jar>\clojure-1.5.1.jar" target\lib\
        1 file(s) copied.

জাভা পার্ট

লিনিনগেনের একটি অন্তর্নির্মিত টাস্ক রয়েছে, lein-javacযা জাভা সংকলনে সাহায্য করতে সক্ষম হওয়া উচিত। দুর্ভাগ্যক্রমে, এটি সংস্করণ ২.১.৩ এ বিভক্ত বলে মনে হচ্ছে। এটি ইনস্টল করা জেডিকে খুঁজে পাচ্ছে না এবং এটি ম্যাভেন সংগ্রহশালাটি খুঁজে পাবে না। উভয় পথেই আমার সিস্টেমে এম্বেড শূন্যস্থান রয়েছে। আমি ধরে নিলাম যে সমস্যা। যেকোন জাভা আইডিই সংকলন এবং প্যাকেজিং পরিচালনা করতে পারে। তবে এই পোস্টের জন্য, আমরা পুরানো স্কুলে যাচ্ছি এবং কমান্ড লাইনে এটি করছি।

প্রথমে Main.javaমূল উত্তরে প্রদর্শিত সামগ্রীর সাহায্যে ফাইলটি তৈরি করুন ।

জাভা অংশ সংকলন করতে

javac -g -cp target\com.domain.tiny-0.1.0-SNAPSHOT.jar -d target\src\com\domain\Main.java

আমরা যে জারটি তৈরি করতে চাই তাতে যোগ করতে এখন কিছু মেটা-তথ্য দিয়ে একটি ফাইল তৈরি করুন। ইন Manifest.txt, নিম্নলিখিত পাঠ্য যোগ করুন

Class-Path: lib\com.domain.tiny-0.1.0-SNAPSHOT.jar lib\clojure-1.5.1.jar
Main-Class: Main

এখন আমাদের ক্লোজার প্রোগ্রাম এবং ক্লোজার জার সহ এটি একটি বড় জার ফাইলে প্যাকেজ করুন।

C:\projects\com.domain.tiny\target>jar cfm Interop.jar Manifest.txt Main.class lib\com.domain.tiny-0.1.0-SNAPSHOT.jar lib\clojure-1.5.1.jar

প্রোগ্রামটি চালাতে:

C:\projects\com.domain.tiny\target>java -jar Interop.jar
(binomial 5 3): 10.0
(binomial 10042, 111): 4.9068389575068143E263

আউটপুটটি ক্লোজিউরের একা উত্পাদিত মূলত অভিন্ন, তবে ফলাফলটি জাভা ডাবলে রূপান্তরিত হয়েছে।

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


4
1. " ক্লোজুরডোকস.আর.এস ." এর উদাহরণ হিসাবে আমি কী "এনএস" ম্যাক্রোর উদাহরণ দিতে পারি? ২. ":" এর সামনে # is কী: পদ্ধতিগুলি [# ^ {: স্থির সত্য} [দ্বিপদী [অন্তর্নিহিত] দ্বিগুণ]] "(আমি একজন নবাগত)?
বেলুন

5
@ বেলুন, নিশ্চিত আপনি এটি একটি উদাহরণ হিসাবে ব্যবহার করতে পারেন - আমি চাটুকার। "# ^ Stat: স্ট্যাটিক ট্রু}" কিছু ফর্মের সাথে মেটাডেটা সংযুক্ত করে যা ইঙ্গিত করে যে দ্বিপদী একটি স্ট্যাটিক ফাংশন। এটি এক্ষেত্রে প্রয়োজনীয় কারণ জাভা সাইডে, আমরা ফাংশনটিকে মূল থেকে কল করছি - একটি স্থির ফাংশন। দ্বিপদী স্থির না হলে জাভা দিকের মূল ফাংশনটি সংকলন করে "স্থিতিশীল পদ্ধতি বিনম (int, int) কোনও স্থির প্রসঙ্গ থেকে রেফারেন্স করা যায় না" সম্পর্কে একটি ত্রুটি বার্তা তৈরি করে। অবজেক্ট মেন্টর সাইটে অতিরিক্ত উদাহরণ রয়েছে।
ক্লারটাক

4
এখানে একটি গুরুত্বপূর্ণ বিষয় উল্লেখ করা হয়নি - জাভা ক্লাসে ক্লোজার ফাইলটি সংকলন করতে আপনার দরকার: ('com.domain.tiny' সংকলন করুন)
ডোমচি

আপনি কীভাবে ক্লোজার উত্সটি সংকলন করছেন? এখানেই আমি আটকে আছি।
ম্যাথু বোস্টন

@ ম্যাথেজবস্টন সেই সময় উত্তরটি লেখা হয়েছিল, আমি নেটবিয়ান আইডিইয়ের জন্য একটি প্লাগইন এনক্লোজার ব্যবহার করেছি। এখন, আমি সম্ভবত লেইনিঞ্জেন ব্যবহার করব, তবে এটির চেষ্টা বা পরীক্ষা করিনি।
ক্লারটাক

119

Clojure 1.6.0 হিসাবে ক্লোজার ফাংশন লোড করা এবং প্রার্থনা করার জন্য একটি নতুন পছন্দসই উপায় রয়েছে। এই পদ্ধতিটি এখন আরটিকে সরাসরি কল করতে পছন্দ করা হয় (এবং এখানে অন্যান্য উত্তরগুলির অনেকগুলি ছাড়িয়ে যায়)। জাভাদোক এখানে - প্রধান প্রবেশ পয়েন্টটিclojure.java.api.Clojure

ক্লোজার ফাংশনটি দেখতে এবং কল করতে:

IFn plus = Clojure.var("clojure.core", "+");
plus.invoke(1, 2);

এতে ফাংশনগুলি clojure.coreস্বয়ংক্রিয়ভাবে লোড হয়। অন্যান্য নেমস্পেসগুলি প্রয়োজনের মাধ্যমে লোড করা যায়:

IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("clojure.set"));

IFnগুলি উচ্চতর ক্রম ফাংশন প্রেরণ করা যেতে পারে, পাস নীচের উদাহরণে যেমন plusকরতে read:

IFn map = Clojure.var("clojure.core", "map");
IFn inc = Clojure.var("clojure.core", "inc");
map.invoke(inc, Clojure.read("[1 2 3]"));

IFnক্লোজারে বেশিরভাগ গুলি ফাংশনগুলি উল্লেখ করে। কয়েক, তবে, অ-কার্যকারিতা ডেটা মানগুলিকে উল্লেখ করে। এগুলি অ্যাক্সেস করতে এর derefপরিবর্তে ব্যবহার করুন fn:

IFn printLength = Clojure.var("clojure.core", "*print-length*");
IFn deref = Clojure.var("clojure.core", "deref");
deref.invoke(printLength);

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

Class.forName("clojure.java.api.Clojure") 

1
এই পদ্ধতির ব্যবহার করে, স্ক্রিপ্টটি উদ্ধৃতি '() ব্যবহার করতে পারে না এবং জিনিসগুলির প্রয়োজন হয় না। তার কি কোনও সমাধান আছে?
রেনাটো

2
আমি মনে করি কেবলমাত্র দুটি বিশেষ ফর্ম রয়েছে যা ভারস হিসাবেও বিদ্যমান নেই। এটির মাধ্যমে অ্যাক্সেস করা এক কাজ Clojure.read("'(1 2 3")। Clojure.quote () সরবরাহ করার জন্য বা এটি কোনও ভ্যার হিসাবে কাজ করে যদিও এটি বর্ধিতকরণ অনুরোধ হিসাবে এটিকে ফাইল করা যুক্তিসঙ্গত হবে।
অ্যালেক্স মিলার

1
@ রেনাটো কোনও কিছুর উদ্ধৃতি দেওয়ার দরকার নেই, কারণ ক্লোজারের মূল্যায়নের বিধি দ্বারা যে কোনওভাবেই মূল্যায়ন করা হচ্ছে না। আপনি যদি ১-২ নম্বর সংবলিত একটি তালিকা চান তবে লেখার পরিবর্তে '(1 2 3)আপনার মতো কিছু লিখুন Clojure.var("clojure.core", "list").invoke(1,2,3)। এবং উত্তরটিতে ইতিমধ্যে কীভাবে ব্যবহার করা যায় তার একটি উদাহরণ রয়েছে require: এটি অন্য কোনওর মতো কেবল একটি বৈচিত্র্য।
অমলয়

34

সম্পাদনা এই উত্তরটি ২০১০ সালে লেখা হয়েছিল এবং সেই সময়ে এটি কাজ করেছিল। আরও আধুনিক সমাধানের জন্য অ্যালেক্স মিলারের উত্তর দেখুন।

জাভা থেকে কোন ধরণের কোড কল করা হচ্ছে? আপনার যদি জেনার-ক্লাস দিয়ে ক্লাস উত্পন্ন হয়, তবে কেবল এটিকে কল করুন। আপনি যদি স্ক্রিপ্ট থেকে ফাংশন কল করতে চান, তবে নিম্নলিখিত উদাহরণটি দেখুন

আপনি যদি জাভাতে স্ট্রিং থেকে কোডটি মূল্যায়ন করতে চান তবে নীচের কোডটি ব্যবহার করতে পারেন:

import clojure.lang.RT;
import clojure.lang.Var;
import clojure.lang.Compiler;
import java.io.StringReader;

public class Foo {
  public static void main(String[] args) throws Exception {
    // Load the Clojure script -- as a side effect this initializes the runtime.
    String str = "(ns user) (defn foo [a b]   (str a \" \" b))";

    //RT.loadResourceScript("foo.clj");
    Compiler.load(new StringReader(str));

    // Get a reference to the foo function.
    Var foo = RT.var("user", "foo");

    // Call it!
    Object result = foo.invoke("Hi", "there");
    System.out.println(result);
  }
}

1
যদি আপনি নেমস্পেসের ডিফ'ড ভারে অ্যাক্সেস করতে চান তবে কিছুটা প্রসারিত করতে (যেমন (ডিএফ মাই-ভার 10)) এটি ব্যবহার করুন RT.var("namespace", "my-var").deref()
ইভান কোব্লিক

এটি RT.load("clojure/core");শুরুতে যোগ না করে আমার পক্ষে কাজ করে না । কি আজব আচরণ?
hsestupin

এটি কাজ করে এবং আমি যা ব্যবহার করে চলেছি তার অনুরূপ; এটি নতুন প্রযুক্তি কিনা নিশ্চিত না। আমি Clojure 1.4 বা 1.6 ব্যবহার করা হতে পারে তা নিশ্চিত নয়।
ইয়ান কিং ইয়িন

12

সম্পাদনা: আমি এই উত্তরটি প্রায় তিন বছর আগে লিখেছি। Clojure 1.6 এ জাভা থেকে ক্লোজারকে কল করার উদ্দেশ্যে ঠিক একটি যথাযথ এপিআই রয়েছে। আপ টু ডেট তথ্যের জন্য দয়া করে অ্যালেক্স মিলারের উত্তর দিন।

২০১১ সালের আসল উত্তর:

আমি এটি দেখতে পাচ্ছি, সবচেয়ে সহজ উপায় (যদি আপনি এওটি সংকলন সহ কোনও শ্রেণি উত্পন্ন করেন না) হ'ল ক্লোজারে ফাংশনগুলি অ্যাক্সেস করতে Clojure.lang.RT ব্যবহার করা। এটির সাহায্যে আপনি ক্লোজুরে যা করেছেন তা নকল করতে পারেন (বিশেষ উপায়ে জিনিসগুলি সংকলনের প্রয়োজন নেই):

;; Example usage of the "bar-fn" function from the "foo.ns" namespace from Clojure
(require 'foo.ns)
(foo.ns/bar-fn 1 2 3)

এবং জাভাতে:

// Example usage of the "bar-fn" function from the "foo.ns" namespace from Java
import clojure.lang.RT;
import clojure.lang.Symbol;
...
RT.var("clojure.core", "require").invoke(Symbol.intern("foo.ns"));
RT.var("foo.ns", "bar-fn").invoke(1, 2, 3);

এটি জাভাতে আরও কিছুটা ভার্বোজ, তবে আমি আশা করি এটি পরিষ্কার হয়ে গেছে যে কোডের টুকরা সমান।

ক্লোজার এবং আপনার ক্লোজার কোডের উত্স ফাইলগুলি (বা সংকলিত ফাইল) ক্লাসপথে রয়েছে ততক্ষণ এটি কাজ করা উচিত।


1
এই পরামর্শটি Clojure 1.6 হিসাবে পুরানো - দয়া করে পরিবর্তে Clojure.java.api. ক্লোজার ব্যবহার করুন।
অ্যালেক্স মিলার

না সময়ে একটি খারাপ উত্তর, কিন্তু আমি খয়রাত বোঝানো stackoverflow.com/a/23555959/1756702 Clojure 1.6 জন্য প্রামাণিক উত্তর হিসাবে। আগামীকাল আবার চেষ্টা করবে ...
এ। ওয়েব

অ্যালেক্সের উত্তর অবশ্যই অনুগ্রহের দাবিদার! প্রয়োজনে অনুগ্রহ হস্তান্তর করতে যদি আমি সহায়তা করতে পারি তবে দয়া করে আমাকে জানান।
রেকে

@ ইরাক আমার আপত্তি নেই যে আপনি আমার ওভার ক্যাফিনেটেড ট্রিগার আঙুল থেকে কিছুটা বোনাস পেয়েছেন। আশা করি আপনাকে আবার ক্লোজার টেগের সাথে দেখা হবে।
উ। ওয়েব

10

আমি ক্লারতাকের উত্তরের সাথে একমত, তবে আমি অনুভব করেছি যে নতুনরাও এটি ব্যবহার করতে পারেন:

  • কীভাবে আসলে এই দৌড়াদৌড়ি পাওয়া যায় সে সম্পর্কে ধাপে ধাপে তথ্য
  • ক্লোজার 1.3 এবং লেনিনজেনের সাম্প্রতিক সংস্করণগুলির জন্য বর্তমান তথ্য।
  • একটি ক্লোজার জার যা একটি প্রধান ফাংশনও অন্তর্ভুক্ত করে, তাই এটি স্ট্যান্ডলোন চালানো যায় বা লাইব্রেরি হিসাবে সংযুক্ত করা যেতে পারে ।

সুতরাং আমি এই ব্লগ পোস্টে সমস্ত আবরণ

ক্লোজার কোডটি দেখতে এমন দেখাচ্ছে:

(ns ThingOne.core
 (:gen-class
    :methods [#^{:static true} [foo [int] void]]))

(defn -foo [i] (println "Hello from Clojure. My input was " i))

(defn -main [] (println "Hello from Clojure -main." ))

লেনিনজেঞ্জ ১..1.১ প্রকল্পের সেটআপটি এর মতো দেখাচ্ছে:

(defproject ThingOne "1.0.0-SNAPSHOT"
  :description "Hello, Clojure"
  :dependencies [[org.clojure/clojure "1.3.0"]]
  :aot [ThingOne.core]
  :main ThingOne.core)

জাভা কোডটি দেখতে এমন দেখাচ্ছে:

import ThingOne.*;

class HelloJava {
    public static void main(String[] args) {
        System.out.println("Hello from Java!");
        core.foo (12345);
    }
}

অথবা আপনি এই প্রকল্পটি থেকে গিথুবে সমস্ত কোডও পেতে পারেন ।


আপনি কেন এওটি ব্যবহার করলেন? এটি কি প্রোগ্রামটিকে আর প্ল্যাটফর্ম-ইন্ডিপেন্ডেটে পরিণত করে না?
এডওয়ার্ড

3

এটি Clojure 1.5.0 সাথে কাজ করে:

public class CljTest {
    public static Object evalClj(String a) {
        return clojure.lang.Compiler.load(new java.io.StringReader(a));
    }

    public static void main(String[] args) {
        new clojure.lang.RT(); // needed since 1.5.0        
        System.out.println(evalClj("(+ 1 2)"));
    }
}

2

যদি জাভা অ্যাপ্লিকেশনটিতে ক্লোজারের সাথে নির্মিত একটি জেআর ব্যবহারের ক্ষেত্রে অন্তর্ভুক্ত করা হয় তবে আমি দুটি বিশ্বের মধ্যে ইন্টারফেসের জন্য একটি পৃথক নেমস্পেস থাকা উপকারী বলে খুঁজে পেয়েছি:

(ns example-app.interop
  (:require [example-app.core :as core])

;; This example covers two-way communication: the Clojure library 
;; relies on the wrapping Java app for some functionality (through
;; an interface that the Clojure library provides and the Java app
;; implements) and the Java app calls the Clojure library to perform 
;; work. The latter case is covered by a class provided by the Clojure lib.
;; 
;; This namespace should be AOT compiled.

;; The interface that the java app can implement
(gen-interface
  :name com.example.WeatherForecast
  :methods [[getTemperature [] Double]])

;; The class that the java app instantiates
(gen-class
  :name com.example.HighTemperatureMailer
  :state state
  :init init
  ;; Dependency injection - take an instance of the previously defined
  ;; interface as a constructor argument
  :constructors {[com.example.WeatherForecast] []}
  :methods [[sendMails [] void]])

(defn -init [weather-forecast]
  [[] {:weather-forecast weather-forecast}])

;; The actual work is done in the core namespace
(defn -sendMails
  [this]
  (core/send-mails (.state this)))

মূল নেমস্পেসটি এর কাজগুলি সম্পাদন করতে ইঞ্জেকড উদাহরণটি ব্যবহার করতে পারে:

(ns example-app.core)

(defn send-mails 
  [{:keys [weather-forecast]}]
  (let [temp (.getTemperature weather-forecast)] ...)) 

পরীক্ষার উদ্দেশ্যে, ইন্টারফেসটি স্টাব করা যেতে পারে:

(example-app.core/send-mails 
  (reify com.example.WeatherForecast (getTemperature [this] ...)))

0

জেভিএম-এর শীর্ষে অন্যান্য ভাষার সাথেও কাজ করে এমন অন্যান্য কৌশল হ'ল আপনি যে ফাংশনগুলিতে কল করতে চান তার জন্য একটি ইন্টারফেস ঘোষণা করা এবং তারপরে তাদের প্রয়োগকারী উদাহরণ তৈরি করতে 'প্রক্সি' ফাংশন ব্যবহার করুন।


-1

আপনি ক্লোজার কোডটি উপস্থাপন করে ক্লাস ফাইলগুলি তৈরি করতে আপনি এওটি সংকলনটিও ব্যবহার করতে পারেন। এটি কীভাবে করবেন সে সম্পর্কে বিশদ জন্য ক্লোজার এপিআই ডক্সে সংকলন, জেনার-ক্লাস এবং বন্ধুদের সম্পর্কে ডকুমেন্টেশন পড়ুন, তবে সংক্ষেপে আপনি এমন একটি শ্রেণি তৈরি করবেন যা প্রতিটি পদ্ধতির অনুরোধের জন্য ক্লোজার ফাংশনকে ডাকে।

আরেকটি বিকল্প হ'ল নতুন ডিফপ্রোটোকল এবং ডিফ্টাইপ কার্যকারিতা ব্যবহার করা, যার জন্য এওটি সংকলনের প্রয়োজন হবে তবে আরও ভাল পারফরম্যান্স সরবরাহ করা হবে। এটি কীভাবে করবেন তার বিশদ আমি জানি না, তবে মেলিং তালিকার একটি প্রশ্ন সম্ভবত কৌশলটি করবে।

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