Skip to content

Home

Find and Kill Processes Locking Specific Ports on a Mac

Problem: Sometimes, when you start a local Node.js server, it may continue running in the background. If you try to start the server again, you may encounter an error indicating that the port (e.g., 8080) is already in use and locked:

    throw er; // Unhandled 'error' event
    Error: listen EADDRINUSE 127.0.0.1:8080

Solution: You can use the lsof command to identify the process locking the port:

    lsof -n -i4TCP:8080

Alternatively, you can replace 8080 with the specific port number you want to investigate. This will display a list of processes currently using that port. Identify the process you wish to terminate (for example, node running with PID 6709) and execute the following command to kill it:

    kill -9 <PID>

Finally, restart your server. It should run normally once the port has been freed.

Find and Kill Processes Locking Specific Ports on a Mac

Welcome to "Continuous Improvement," the podcast where we explore tips, tricks, and solutions for overcoming development hurdles. I'm your host, Victor, and in today's episode, we'll be discussing a common issue many developers encounter while working with Node.js servers: the dreaded port lock error.

Have you ever tried to start a local Node.js server only to find out that the port you want to use is already in use and locked? It can be quite frustrating, but fear not, because today we have a solution for you.

The problem occurs when you try to start your server and receive an error message that says, "Error: listen EADDRINUSE..." followed by the IP address and port number. But worry not, there's a way to identify which process is locking that port.

One method is to utilize the command-line tool called lsof. Simply open your terminal, and type in lsof -n -i4TCP:<port>. Replace <port> with the specific port number you want to investigate, such as 8080.

Once you execute this command, you'll be provided with a list of processes currently using that port. Take note of the process you wish to terminate. For example, you might see a process like node running with a PID (Process ID) of 6709.

Now comes the moment of truth. Execute the following command to kill the process and free up the locked port: kill -9 <PID>. Remember to replace <PID> with the actual Process ID you want to terminate, in this case, 6709.

Once you've successfully terminated the process, you're almost out of the woods. Now you can restart your server, and it should run normally without encountering the port lock error.

And there you have it! A simple yet effective solution for tackling the port lock issue in Node.js. Remember to use the lsof command to identify the process locking the port, and then terminate it using kill -9 <PID>.

That concludes today's episode of "Continuous Improvement". I hope this solution will help you overcome any port-related obstacles you may encounter in your development journey. Thanks for listening, and until next time, keep striving for continuous improvement in your coding endeavors.

在 Mac 上尋找並終止鎖定特定端口的進程

問題:有時候,當您啟動一個本地 Node.js 服務器時,它可能會繼續在後台運行。如果您嘗試再次啟動服務器,您可能會遇到一個錯誤,指出端口(例如,8080)已經在使用中並被鎖定:

    throw er; // Unhandled 'error' event
    Error: listen EADDRINUSE 127.0.0.1:8080

解決方案:您可以使用 lsof 命令來識別鎖定端口的進程:

    lsof -n -i4TCP:8080

或者,您可以將 8080 替換為您想要調查的特定端口號。這將顯示當前使用該端口的進程列表。識別您希望終止的進程(例如,正在運行的 node 與 PID 6709)並執行以下命令來將其殺死:

    kill -9 <PID>

最後,重新啟動您的服務器。一旦端口被釋放,它應該可以正常運行。

How to Work with a Product Manager as a Software Engineer

As a software engineer, I know how it feels to work with product managers. With years of experience, I've encountered fantastic Product Managers (PMs) as well as some less-than-ideal ones. Every day, I collaborate with PMs, and I understand the challenges that can arise, particularly when the relationship is strained. In this blog post, I'll offer advice on how to work effectively with a PM as a software engineer.

Two primary difficulties can arise when working with PMs. The first issue is that a PM without an engineering background may not understand the technical complexities you're dealing with, leading to a lack of mutual respect. Secondly, if a PM started their career as an engineer, it can be frustrating to hear them talk as if they fully understand technical subjects like blockchains, big data, or artificial intelligence when they actually don't.

To bridge these gaps, soft skills and communication abilities are essential.

Common Pitfall 1: Technological Ignorance

The worst thing to hear from a PM is something like, "It's just a simple button. Are you sure you can't finish it in five minutes?" Such comments imply that the work is straightforward and that you are incompetent. But, creating even a simple button is not trivial. For example, Google's homepage search button is not just a "simple button." Various states like hover, click, double-click, and other factors like text localization, accessibility, and multiple screen widths must be considered.

Common Mistake 2: Misunderstanding Roles and Responsibilities

PMs are responsible for the product, but they are not your bosses. This misunderstanding can be especially prevalent in hierarchical organizational structures or where an outsourced vendor manages in-house PMs. Practicing methodologies like Scrum can help set boundaries and manage expectations. Frequent changes in requirements can be detrimental to the project, leading to non-reusable code, bugs, and technical debt.

Common Error 3: Lack of Clear Objectives

It can be frustrating when a PM has no clear vision and hasn't defined specific requirements. Engineers thrive on tackling challenges and require clear goals. Poorly defined requirements lead to a product that's hard to measure in terms of impact and success.

Final Thoughts

To navigate these issues successfully, here are my three recommendations:

  1. Treat non-technical stakeholders with empathy and kindness, while educating them on the complexities of your work.
  2. Understand that the PM is not your boss; collaborate and be willing to share credit for successes.
  3. Stay informed about industry trends and be prepared to construct a persuasive argument when you think the requirements are flawed.

Remember, software development is a team sport. Like any team, success depends on effective communication, collaboration, and leadership to achieve a common goal.

How to Work with a Product Manager as a Software Engineer

Welcome to "Continuous Improvement," the podcast where we delve into the world of software engineering and explore ways to enhance our skills and improve our professional lives. I'm your host, Victor, and in today's episode, we'll be discussing a common challenge faced by software engineers – working effectively with product managers. Whether you've had great experiences or not-so-great ones, we'll explore some practical advice to help you navigate these working relationships. So let's jump right in!

One of the primary difficulties when working with product managers is the gap in technical understanding. As software engineers, we often face challenges that go beyond what seems apparent to others. It's frustrating to hear phrases like, "It's just a simple button. Can't you finish it quickly?" These comments undermine the complexity of our work and can lead to a lack of mutual respect.

Take, for example, the search button on Google's homepage. It may seem simple, but it's not just an ordinary button. From considering different states like hover, click, double-click, to accounting for text localization, accessibility, and various screen widths – it requires meticulous attention to detail. By educating PMs about these complexities with empathy and kindness, we can bridge the gap and foster a more collaborative environment.

Another challenge arises when the roles and responsibilities between engineers and product managers are misunderstood. In hierarchical organizational structures, or when outsourced vendors manage in-house PMs, it's easy to fall into the belief that PMs are our bosses. However, PMs are accountable for the product, not our direct supervisors. Implementing methodologies like Scrum can help establish boundaries and shape realistic expectations.

When requirements constantly change, it not only disrupts our workflow but also hampers the quality of our code. Non-reusable code, bugs, and technical debt become persistent issues, leading to a stressful work environment. Clear communication and collaboration are key to navigating these challenges successfully.

Lastly, a lack of clear objectives can be a significant hindrance to software engineers. We thrive on tackling challenges and require clear goals to measure our impact and achieve success. When PMs fail to define specific requirements and provide a clear vision, it's important to approach them constructively and communicate the need for clarity. By highlighting the importance of well-defined objectives, we can create a more productive working environment.

To sum it all up, let me share three recommendations for working effectively with PMs:

  1. Treat non-technical stakeholders with empathy and kindness while educating them about the technical complexities you face.
  2. Keep in mind that PMs are not your bosses; foster a collaborative environment and be willing to share credit for successes.
  3. Stay updated on industry trends and be prepared to construct persuasive arguments when you believe the requirements are flawed.

Remember, software development is a team sport, and effective communication, collaboration, and leadership are vital for success. By embracing these practices, we can enhance our working relationships with product managers and create a more productive and enjoyable work environment.

That's all for this episode of "Continuous Improvement." I hope you found these insights helpful in navigating your interactions with product managers. If there's a specific topic you'd like me to cover in a future episode, feel free to reach out and let me know. Until next time, keep striving for continuous improvement in your software engineering journey!

作為一名軟件工程師如何與產品經理合作

作為一名軟件工程師,我知道與產品經理合作的感覺。借助多年的經驗,我遇到過優秀的產品經理(PM)以及一些不理想的PM。每天,我都會與PM進行合作,我了解到可能出現的挑戰,特別是當彼此的關係變得緊張時。在這篇博客文章中,我將提供一些作為一名軟件工程師如何有效與PM合作的建議。

與PM合作時可能出現兩個主要的困難。第一個問題是,沒有工程背景的PM可能無法理解你正在處理的技術復雜性,導致彼此之間缺乏尊重。第二,如果PM的職業生涯始於工程師,他們如果說出自己完全理解像區塊鏈、大數據或人工智能等技術主題,實際上卻不然,會讓人感到困擾。

要縮小這些隔閡,軟技能和溝通能力是必不可少的。

常見的陷阱1:對科技的無知

從PM那裡聽到最讓人惱火的一句話可能就是, "這只是一個簡單的按鈕。你確定你五分鐘內完成不了嗎?"之類的評論暗示著工作很簡單,並且你是無能的。但是,創建即使是一個簡單的按鈕也並非小事。例如,Google首頁的搜索按鈕不只是一個”簡單的按鈕”。必須要考慮各種狀況,如懸停、點擊、雙擊,以及像文本語言化,訪問性和多個屏幕寬度等其他因素。

常見的錯誤2:誤解角色和責任

PM負責產品,但他們不是你的老闆。在等級組織結構中或者是由外包廠商管理的內部PM中,這種誤解可能尤其普遍。採用像精益求精這樣的方法可以幫助設定邊界並管理期望。需求的頻繁變更可能對項目造成傷害,導致無法重用的代碼,錯誤和技術債務。

常見的錯誤3:沒有清晰的目標

在PM沒有明確的願景並沒有定義具體的需求時,可能會讓人感到沮喪。工程師擅長解決挑戰並需要清晰的目標。需求定義不明會導致產品難以衡量影響和成功。

最後的想法

為了成功地應對這些問題,這裡有我的三個建議:

  1. 以同理心和善意對待非技術的利益相關者,同時讓他們了解你工作的復雜性。
  2. 理解PM並不是你的老闆;願意與他們合作並願意分享成功的成果。
  3. 對行業趨勢保持了解,並準備好在你認為需求有誤時進行有說服力的論述。

請記住,軟件開發是一個團隊運動。像任何隊伍一樣,成功取決於有效的溝通,合作和領導以實現共同的目標。

Registering Sling Servlets in Adobe Experience Manager

In Adobe Experience Manager (AEM), a Sling servlet can be utilized to handle certain RESTful request-response AJAX calls. Written in the Java programming language, these servlets can be registered as OSGi (Open Services Gateway Initiative) services. There are two methods to register a servlet in AEM: 1) By Path, and 2) By resourceType. Details for both are explained below:

1. Register by Path

For instance, if you want to execute a form POST request to the path /bin/payment from the client-side to the Sling servlet class, you can use the annotation below:

@SlingServlet(
    metatype = true,
    methods = { "POST" },
    paths = "/bin/payment"
)
public class YourServlet extends SlingSafeMethodsServlet {

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException {
        // Perform your tasks here
    }
}

When there's a POST request to http://localhost:4502/bin/payment, the servlet will be triggered, and the doPost method will be invoked.

Prerequisites include having a local AEM instance up and running on port 4502 and installing the bundle module via the Maven bundle plugin. You can verify the installation of the bundle by navigating to http://localhost:4502/system/console/bundles. If it's not installed, you can manually upload the JAR file.

If you encounter a "forbidden" error and cannot serve the request to /bin/payment, follow these steps:

  1. Go to http://localhost:4502/system/console/configMgr.
  2. Search for 'Apache Sling Referrer Filter'.
  3. Remove the POST method from the filter. This will allow you to trigger the POST method from any source.
  4. Locate Adobe Granite CSRF Filter.
  5. Remove POST from the filter methods.
  6. Save the changes and test the servlet again.

The servlet should now trigger as expected.

2. Register by resourceType

To avoid the issues mentioned above, a better approach is to register the servlet by resourceType. Refactor the servlet as follows:

@SlingServlet(
    metatype = true,
    methods = { "POST" },
    resourceTypes = "services/payment"
)
public class YourServlet extends SlingSafeMethodsServlet {

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException {
        // Perform your tasks here
    }
}

Next, you'll need to create a page to trigger this resource:

  1. Go to CRXDE Lite at http://localhost:4502/crx/de/index.jsp.
  2. Inside the /content folder, create a page (e.g., http://localhost:4502/content/submitPage.html).
  3. In the resourceType properties, enter services/payment or whatever matches your servlet above.
  4. Save your changes and test the POST request to http://localhost:4502/content/submitPage.html. It should work as expected.

Extra Tips: You can also use the Apache Sling Resource Resolver to verify if the servlet has been registered successfully at http://localhost:4502/system/console/jcrresolver.

Feel free to leave any questions in the comments below.

Registering Sling Servlets in Adobe Experience Manager

Hello, and welcome to "Continuous Improvement," the podcast that provides tips, insights, and strategies for enhancing your skills in software development. I'm your host, Victor.

In today's episode, we'll dive into the world of Adobe Experience Manager and explore how to handle RESTful request-response AJAX calls using Sling servlets. We'll discuss two methods to register these servlets in AEM - by path and by resourceType. So, let's get started!

Sling servlets, written in Java, are designed to handle specific AJAX calls within AEM applications. They can be registered as OSGi services and are useful for executing various tasks based on incoming requests.

Let's begin with the first method - registering a servlet by path. Imagine you want to handle a form POST request at the path /bin/payment. To do this, you'll need to annotate your servlet class using the following code:

[Code Mention]

This annotation ensures that your servlet is triggered when a POST request is sent to http://localhost:4502/bin/payment. The doPost method within the servlet class will be invoked, allowing you to perform your desired tasks.

It's important to have a local AEM instance running on port 4502 and install the bundle module using the Maven bundle plugin before registering your servlet. You can check if the bundle is installed by navigating to http://localhost:4502/system/console/bundles. If it's not installed, you can manually upload the JAR file.

Now, what happens if you encounter a "forbidden" error when trying to serve a request to /bin/payment? Don't worry; I've got you covered!

Here's what you can do:

  1. Go to http://localhost:4502/system/console/configMgr.
  2. Search for 'Apache Sling Referrer Filter'.
  3. Remove the POST method from the filter. This step allows triggering the POST method from any source.
  4. Locate Adobe Granite CSRF Filter.
  5. Remove the POST method from the filter methods as well.
  6. Save the changes and give your servlet another try.

By following these steps, you should be able to resolve the "forbidden" error and successfully trigger your servlet.

Now, let's move on to the second method - registering a servlet by resourceType. This approach is more flexible and avoids the aforementioned issues. Here's how you can do it:

[Code Mention]

Refactor your servlet by using this annotation and specify the desired resourceType. For example, services/payment or any other resourceType that matches your servlet. This way, your servlet will be triggered by requests to pages with the specified resourceType.

To test your servlet, you'll need to create a page that triggers its resourceType:

  1. Go to CRXDE Lite at http://localhost:4502/crx/de/index.jsp.
  2. Inside the /content folder, create a page, for example, http://localhost:4502/content/submitPage.html.
  3. In the resourceType properties, enter services/payment or the corresponding resourceType from your servlet.
  4. Save your changes and test the POST request by visiting http://localhost:4502/content/submitPage.html. It should work as expected.

An extra tip for you! You can use the Apache Sling Resource Resolver at http://localhost:4502/system/console/jcrresolver to verify if your servlet has been successfully registered.

And that wraps up today's episode of "Continuous Improvement." We explored the world of Sling servlets in Adobe Experience Manager, discussing how to register them by both path and resourceType.

Thank you for joining me, Victor, your host, on this journey of continuous improvement. I hope you found today's episode valuable in expanding your skills as a software developer.

If you have any questions or comments, feel free to reach out in the comments section of the associated blog post.

Don't forget to subscribe to "Continuous Improvement" for more insightful episodes and updates. Until next time, keep striving for excellence and embracing the world of continuous improvement.

在Adobe Experience Manager中註冊Sling Servlets

在Adobe Experience Manager (AEM) 中,Sling servlet可以被用來處理某些RESTful的請求-回應的AJAX調用。寫在Java編程語言中的Servlets可以被註冊為OSGi(開放服務網關協議)服務。在AEM中註冊servlet有兩種方法:1) 通過路徑,和 2) 通過資源類型。以下是兩種方法的詳細說明:

1. 通過路徑註冊

例如,如果您希望從客戶端發送一個表單POST請求到路徑/bin/payment 到Sling servlet類,您可以使用以下的註解:

@SlingServlet(
    metatype = true,
    methods = { "POST" },
    paths = "/bin/payment"
)
public class YourServlet extends SlingSafeMethodsServlet {

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException {
        // 在這裡執行你的任務
    }
}

當有一個POST請求到 http://localhost:4502/bin/payment 時,servlet將被觸發,並調用 doPost 方法。

前提條件包括在端口4502上運行本地AEM實例,並通過Maven Bundle插件安裝bundle模組。您可以通過導航到 http://localhost:4502/system/console/bundles來驗證bundle的安裝。如果沒有安裝,您可以手動上傳JAR文件。

如果您遭遇“禁止”的錯誤,無法服務 /bin/payment 的請求,請按照以下步驟操作:

  1. 轉到 http://localhost:4502/system/console/configMgr
  2. 搜索 'Apache Sling Referrer Filter'。
  3. 從篩選器中刪除POST方法。這將允許您從任何來源觸發POST方法。
  4. 搜索Adobe Granite CSRF Filter。
  5. 從篩選方法中刪除POST。
  6. 保存更改並再次測試servlet。

Servlet現在應該按預期觸發。

2. 通過資源類型註冊

為了避免上述問題,更好的方法是通過資源類型註冊servlet。重構servlet如下:

@SlingServlet(
    metatype = true,
    methods = { "POST" },
    resourceTypes = "services/payment"
)
public class YourServlet extends SlingSafeMethodsServlet {

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException {
        // 在這裡執行你的任務
    }
}

接下來,您需要創建一個頁面來觸發此資源:

  1. 轉到 http://localhost:4502/crx/de/index.jsp的CRXDE Lite。
  2. /content資料夾內,創建一個頁面(例如,http://localhost:4502/content/submitPage.html)。
  3. 在resourceType屬性中,輸入 services/payment 或其他匹配您上述的servlet。
  4. 保存更改並測試POST請求到 http://localhost:4502/content/submitPage.html。 應該可以按预期工作。

額外提示: 您也可以使用Apache Sling Resource Resolver來驗證servlet是否已成功註冊在http://localhost:4502/system/console/jcrresolver

如果有任何問題,可以在下面的評論中留言。

Installing Nextcloud on AWS EC2 with S3 Storage

In an effort to enhance my privacy, I've decided to minimize the use of Google products. I've replaced Chrome with Firefox, switched from Gmail to ProtonMail, and am now using Nextcloud instead of Google Drive. Nextcloud allows for self-hosting of cloud storage and provides control over my own data. Below are the steps to install Nextcloud on AWS EC2 and configure it to use S3 storage.

  1. Install Nextcloud using the Snap package manager:

bash sudo snap install nextcloud

  1. Create an admin user account:

bash sudo nextcloud.manual-install <admin_username> <admin_password>

  1. Add your trusted domain:

bash sudo nextcloud.occ config:system:set trusted_domains 1 --value=<your-domain>

  1. Using AWS Route 53, create an A record that points to the IP address of your Nextcloud server.

  2. Set up an SSL certificate with Let's Encrypt:

bash sudo nextcloud.enable-https lets-encrypt

  1. Navigate to your domain, and you should now be able to log in to your Nextcloud instance.

  1. Click on "Apps" and enable "Default encryption module" and "External storage support."

  2. Open AWS IAM (Identity and Access Management) and create a new user with programmatic access.

  3. Create a new policy using the JSON code below, replacing NAMEOFYOURBUCKET with the name of your S3 bucket. Attach this policy to the newly created user.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetBucketLocation", "s3:ListAllMyBuckets"],
      "Resource": "arn:aws:s3:::*"
    },
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::NAMEOFYOURBUCKET",
        "arn:aws:s3:::NAMEOFYOURBUCKET/*"
      ]
    }
  ]
}
  1. In Nextcloud settings, select "External Storage." Fill in the "Bucket" field with NAMEOFYOURBUCKET. Check "Enable SSL" and "Enable Path Style," then fill in the required information using the credentials of the user you created.

  2. You're done! Navigate to your d3 folder, and you should now be able to upload files.